about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2015-02-20 08:17:05 +0200
committerEduard Burtescu <edy.burt@gmail.com>2015-02-24 14:16:01 +0200
commit06f362aeb3c6956bb471fe44de72185dd831eb48 (patch)
tree2c8559632d78fbbd95f085c829310347957bb3e2
parent6700166442cb88c813e5d3bd39dba3b5f1abc1b0 (diff)
rustc_resolve: don't handle impl items as if they were modules.
-rw-r--r--src/librustc/middle/ty.rs4
-rw-r--r--src/librustc_driver/driver.rs6
-rw-r--r--src/librustc_privacy/lib.rs10
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs238
-rw-r--r--src/librustc_resolve/lib.rs59
-rw-r--r--src/librustc_typeck/check/method/mod.rs13
-rw-r--r--src/librustc_typeck/check/method/probe.rs5
-rw-r--r--src/librustc_typeck/check/method/suggest.rs82
-rw-r--r--src/librustc_typeck/check/mod.rs23
-rw-r--r--src/librustc_typeck/coherence/orphan.rs16
-rw-r--r--src/librustc_typeck/diagnostics.rs1
-rw-r--r--src/test/compile-fail/bad-mid-path-type-params.rs2
-rw-r--r--src/test/compile-fail/generic-impl-less-params-with-defaults.rs2
-rw-r--r--src/test/compile-fail/generic-impl-more-params-with-defaults.rs2
-rw-r--r--src/test/compile-fail/impl-duplicate-methods.rs2
-rw-r--r--src/test/compile-fail/issue-14254.rs10
-rw-r--r--src/test/compile-fail/issue-21202.rs2
-rw-r--r--src/test/compile-fail/issue-2356.rs14
-rw-r--r--src/test/compile-fail/issue-4265.rs2
-rw-r--r--src/test/compile-fail/method-macro-backtrace.rs2
-rw-r--r--src/test/compile-fail/trait-or-new-type-instead.rs4
-rw-r--r--src/test/compile-fail/use-from-trait.rs2
-rw-r--r--src/test/run-pass/impl-not-adjacent-to-type.rs (renamed from src/test/compile-fail/trait-impl-2.rs)22
-rw-r--r--src/test/run-pass/trait-impl-2.rs (renamed from src/test/compile-fail/impl-not-adjacent-to-type.rs)17
24 files changed, 156 insertions, 384 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index c8695ef4ff0..7dcdeaf16d2 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -51,6 +51,7 @@ use middle::dependency_format;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
 use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
 use middle::mem_categorization as mc;
+use middle::privacy::LastPrivateMap;
 use middle::region;
 use middle::resolve_lifetime;
 use middle::infer;
@@ -683,6 +684,7 @@ pub struct ctxt<'tcx> {
     pub sess: Session,
     pub def_map: DefMap,
     pub partial_def_map: PartialDefMap,
+    pub last_private_map: RefCell<LastPrivateMap>,
 
     pub named_region_map: resolve_lifetime::NamedRegionMap,
 
@@ -2426,6 +2428,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
                      arenas: &'tcx CtxtArenas<'tcx>,
                      def_map: DefMap,
                      partial_def_map: PartialDefMap,
+                     last_private_map: LastPrivateMap,
                      named_region_map: resolve_lifetime::NamedRegionMap,
                      map: ast_map::Map<'tcx>,
                      freevars: RefCell<FreevarMap>,
@@ -2449,6 +2452,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         sess: s,
         def_map: def_map,
         partial_def_map: partial_def_map,
+        last_private_map: RefCell::new(last_private_map),
         region_maps: region_maps,
         node_types: RefCell::new(FnvHashMap()),
         item_substs: RefCell::new(NodeMap()),
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index b5933ca11ba..aafa4dec0de 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -609,6 +609,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
                             arenas,
                             def_map,
                             partial_def_map,
+                            last_private_map,
                             named_region_map,
                             ast_map,
                             freevars,
@@ -622,10 +623,9 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     time(time_passes, "const checking", (), |_|
          middle::check_const::check_crate(&ty_cx));
 
-    let maps = (external_exports, last_private_map);
     let (exported_items, public_items) =
-            time(time_passes, "privacy checking", maps, |(a, b)|
-                 rustc_privacy::check_crate(&ty_cx, &export_map, a, b));
+            time(time_passes, "privacy checking", (), |_|
+                 rustc_privacy::check_crate(&ty_cx, &export_map, external_exports));
 
     // Do not move this check past lint
     time(time_passes, "stability index", (), |_|
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 439e4331e35..1452c44ca71 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -38,8 +38,7 @@ use rustc::middle::def;
 use rustc::middle::privacy::ImportUse::*;
 use rustc::middle::privacy::LastPrivate::*;
 use rustc::middle::privacy::PrivateDep::*;
-use rustc::middle::privacy::{ExportedItems, PublicItems, LastPrivateMap};
-use rustc::middle::privacy::{ExternalExports};
+use rustc::middle::privacy::{ExternalExports, ExportedItems, PublicItems};
 use rustc::middle::ty::{MethodTypeParam, MethodStatic};
 use rustc::middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam};
 use rustc::middle::ty::{MethodStaticClosure, MethodObject};
@@ -379,7 +378,6 @@ struct PrivacyVisitor<'a, 'tcx: 'a> {
     in_foreign: bool,
     parents: NodeMap<ast::NodeId>,
     external_exports: ExternalExports,
-    last_private_map: LastPrivateMap,
 }
 
 enum PrivacyResult {
@@ -730,7 +728,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                                    &format!("{} `{}`", tyname, name))
             };
 
-            match self.last_private_map[path_id] {
+            match self.tcx.last_private_map.borrow()[path_id] {
                 LastMod(AllPublic) => {},
                 LastMod(DependsOn(def)) => {
                     self.report_error(ck_public(def));
@@ -1500,8 +1498,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
 
 pub fn check_crate(tcx: &ty::ctxt,
                    export_map: &def::ExportMap,
-                   external_exports: ExternalExports,
-                   last_private_map: LastPrivateMap)
+                   external_exports: ExternalExports)
                    -> (ExportedItems, PublicItems) {
     let krate = tcx.map.krate();
 
@@ -1519,7 +1516,6 @@ pub fn check_crate(tcx: &ty::ctxt,
         tcx: tcx,
         parents: visitor.parents,
         external_exports: external_exports,
-        last_private_map: last_private_map,
     };
     visit::walk_crate(&mut visitor, krate);
 
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index abfb226994a..e4612d6c8b9 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -39,18 +39,16 @@ use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
 use syntax::ast::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
 use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
 use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
-use syntax::ast::{MethodImplItem, Name, NamedField, NodeId};
+use syntax::ast::{Name, NamedField, NodeId};
 use syntax::ast::{PathListIdent, PathListMod, Public};
 use syntax::ast::StmtDecl;
 use syntax::ast::StructVariantKind;
 use syntax::ast::TupleVariantKind;
-use syntax::ast::TyObjectSum;
-use syntax::ast::{TypeImplItem, UnnamedField};
+use syntax::ast::UnnamedField;
 use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
 use syntax::ast::{Visibility};
-use syntax::ast::TyPath;
 use syntax::ast;
-use syntax::ast_util::{self, PostExpansionMethod, local_def};
+use syntax::ast_util::{self, local_def};
 use syntax::attr::AttrMetaMethods;
 use syntax::parse::token::{self, special_idents};
 use syntax::codemap::{Span, DUMMY_SP};
@@ -177,12 +175,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                         Some(TypeNS)
                     }
                     ForbidDuplicateTypesAndModules => {
-                        match child.def_for_namespace(TypeNS) {
-                            None => {}
-                            Some(_) if child.get_module_if_available()
-                                            .map(|m| m.kind.get()) ==
-                                       Some(ImplModuleKind) => {}
-                            Some(_) => duplicate_type = TypeError
+                        if child.defined_in_namespace(TypeNS) {
+                            duplicate_type = TypeError;
                         }
                         Some(TypeNS)
                     }
@@ -461,9 +455,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 name_bindings.define_type(DefTy(local_def(item.id), true), sp, modifiers);
 
                 let parent_link = self.get_parent_link(parent, name);
-                // We want to make sure the module type is EnumModuleKind
-                // even if there's already an ImplModuleKind module defined,
-                // since that's how we prevent duplicate enum definitions
                 name_bindings.set_module_kind(parent_link,
                                               Some(local_def(item.id)),
                                               EnumModuleKind,
@@ -513,133 +504,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 parent.clone()
             }
 
-            ItemImpl(_, _, _, None, ref ty, ref impl_items) => {
-                // If this implements an anonymous trait, then add all the
-                // methods within to a new module, if the type was defined
-                // within this module.
-
-                let mod_name = 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.
-                        Some(path.segments.last().unwrap().identifier.name)
-                    }
-                    TyObjectSum(ref lhs_ty, _) => {
-                        match lhs_ty.node {
-                            TyPath(ref path) if path.segments.len() == 1 => {
-                                Some(path.segments.last().unwrap().identifier.name)
-                            }
-                            _ => {
-                                None
-                            }
-                        }
-                    }
-                    _ => {
-                        None
-                    }
-                };
-
-                let mod_name = match mod_name {
-                    Some(mod_name) => mod_name,
-                    None => {
-                        self.resolve_error(ty.span,
-                                           "inherent implementations may \
-                                            only be implemented in the same \
-                                            module as the type they are \
-                                            implemented for");
-                        return parent.clone();
-                    }
-                };
-                // Create the module and add all methods.
-                let child_opt = parent.children.borrow().get(&mod_name)
-                                       .and_then(|m| m.get_module_if_available());
-                let new_parent = match child_opt {
-                    // It already exists
-                    Some(ref child) if (child.kind.get() == ImplModuleKind ||
-                                        child.kind.get() == TraitModuleKind) => {
-                        child.clone()
-                    }
-                    Some(ref child) if child.kind.get() == EnumModuleKind ||
-                                       child.kind.get() == TypeModuleKind => {
-                        child.clone()
-                    }
-                    // Create the module
-                    _ => {
-                        let name_bindings =
-                            self.add_child(mod_name, parent, ForbidDuplicateModules, sp);
-
-                        let parent_link = self.get_parent_link(parent, name);
-                        let def_id = local_def(item.id);
-                        let ns = TypeNS;
-                        let is_public =
-                            !name_bindings.defined_in_namespace(ns) ||
-                            name_bindings.defined_in_public_namespace(ns);
-
-                        name_bindings.define_module(parent_link,
-                                                    Some(def_id),
-                                                    ImplModuleKind,
-                                                    false,
-                                                    is_public,
-                                                    sp);
-
-                        name_bindings.get_module()
-                    }
-                };
-
-                // For each implementation item...
-                for impl_item in impl_items {
-                    match *impl_item {
-                        MethodImplItem(ref method) => {
-                            // Add the method to the module.
-                            let name = method.pe_ident().name;
-                            let method_name_bindings =
-                                self.add_child(name,
-                                               &new_parent,
-                                               ForbidDuplicateValues,
-                                               method.span);
-                            let def = DefMethod(local_def(method.id),
-                                                FromImpl(local_def(item.id)));
-
-                            // NB: not IMPORTABLE
-                            let modifiers = if method.pe_vis() == ast::Public {
-                                PUBLIC
-                            } else {
-                                DefModifiers::empty()
-                            };
-                            method_name_bindings.define_value(
-                                def,
-                                method.span,
-                                modifiers);
-                        }
-                        TypeImplItem(ref typedef) => {
-                            // Add the typedef to the module.
-                            let name = typedef.ident.name;
-                            let typedef_name_bindings =
-                                self.add_child(
-                                    name,
-                                    &new_parent,
-                                    ForbidDuplicateTypesAndModules,
-                                    typedef.span);
-                            let def = DefAssociatedTy(local_def(item.id),
-                                                      local_def(typedef.id));
-                            // NB: not IMPORTABLE
-                            let modifiers = if typedef.vis == ast::Public {
-                                PUBLIC
-                            } else {
-                                DefModifiers::empty()
-                            };
-                            typedef_name_bindings.define_type(
-                                def,
-                                typedef.span,
-                                modifiers);
-                        }
-                    }
-                }
-                parent.clone()
-            }
-
+            ItemImpl(..) => parent.clone(),
             ItemDefaultImpl(_, _) |
-            ItemImpl(_, _, _, Some(_), _, _) => parent.clone(),
 
             ItemTrait(_, _, _, ref items) => {
                 let name_bindings =
@@ -805,8 +671,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
         let kind = match def {
             DefTy(_, true) => EnumModuleKind,
-            DefTy(_, false) => TypeModuleKind,
-            DefStruct(..) => ImplModuleKind,
+            DefTy(_, false) | DefStruct(..) => TypeModuleKind,
             _ => NormalModuleKind
         };
 
@@ -980,92 +845,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     }
                 }
             }
-            DlImpl(def) => {
-                match csearch::get_type_name_if_impl(&self.session.cstore, def) {
-                    None => {}
-                    Some(final_name) => {
-                        let methods_opt =
-                            csearch::get_methods_if_impl(&self.session.cstore, def);
-                        match methods_opt {
-                            Some(ref methods) if
-                                methods.len() >= 1 => {
-                                debug!("(building reduced graph for \
-                                        external crate) processing \
-                                        static methods for type name {}",
-                                        token::get_name(final_name));
-
-                                let child_name_bindings =
-                                    self.add_child(
-                                        final_name,
-                                        root,
-                                        OverwriteDuplicates,
-                                        DUMMY_SP);
-
-                                // Process the static methods. First,
-                                // create the module.
-                                let type_module;
-                                let type_def = child_name_bindings.type_def.borrow().clone();
-                                match type_def {
-                                    Some(TypeNsDef {
-                                        module_def: Some(module_def),
-                                        ..
-                                    }) => {
-                                        // We already have a module. This
-                                        // is OK.
-                                        type_module = module_def;
-
-                                        // Mark it as an impl module if
-                                        // necessary.
-                                        type_module.kind.set(ImplModuleKind);
-                                    }
-                                    Some(_) | None => {
-                                        let parent_link =
-                                            self.get_parent_link(root, final_name);
-                                        child_name_bindings.define_module(
-                                            parent_link,
-                                            Some(def),
-                                            ImplModuleKind,
-                                            true,
-                                            true,
-                                            DUMMY_SP);
-                                        type_module =
-                                            child_name_bindings.
-                                                get_module();
-                                    }
-                                }
-
-                                // Add each static method to the module.
-                                let new_parent = type_module;
-                                for method_info in methods {
-                                    let name = method_info.name;
-                                    debug!("(building reduced graph for \
-                                             external crate) creating \
-                                             static method '{}'",
-                                           token::get_name(name));
-
-                                    let method_name_bindings =
-                                        self.add_child(name,
-                                                       &new_parent,
-                                                       OverwriteDuplicates,
-                                                       DUMMY_SP);
-                                    let def = DefFn(method_info.def_id, false);
-
-                                    // NB: not IMPORTABLE
-                                    let modifiers = if method_info.vis == ast::Public {
-                                        PUBLIC
-                                    } else {
-                                        DefModifiers::empty()
-                                    };
-                                    method_name_bindings.define_value(
-                                        def, DUMMY_SP, modifiers);
-                                }
-                            }
-
-                            // Otherwise, do nothing.
-                            Some(_) | None => {}
-                        }
-                    }
-                }
+            DlImpl(_) => {
+                debug!("(building reduced graph for external crate) \
+                        ignoring impl");
             }
             DlField => {
                 debug!("(building reduced graph for external crate) \
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 0c5236101cf..6b05a648746 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -514,7 +514,6 @@ enum ParentLink {
 enum ModuleKind {
     NormalModuleKind,
     TraitModuleKind,
-    ImplModuleKind,
     EnumModuleKind,
     TypeModuleKind,
     AnonymousModuleKind,
@@ -1863,13 +1862,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         match import_resolution.value_target {
             Some(ref target) if target.shadowable != Shadowable::Always => {
                 if let Some(ref value) = *name_bindings.value_def.borrow() {
-                    let msg = format!("import `{}` conflicts with value \
-                                       in this module",
-                                      &token::get_name(name));
-                    span_err!(self.session, import_span, E0255, "{}", &msg[..]);
+                    span_err!(self.session, import_span, E0255,
+                              "import `{}` conflicts with value in this module",
+                              &token::get_name(name));
                     if let Some(span) = value.value_span {
-                        self.session.span_note(span,
-                                               "conflicting value here");
+                        self.session.span_note(span, "conflicting value here");
                     }
                 }
             }
@@ -1879,41 +1876,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         match import_resolution.type_target {
             Some(ref target) if target.shadowable != Shadowable::Always => {
                 if let Some(ref ty) = *name_bindings.type_def.borrow() {
-                    match ty.module_def {
-                        None => {
-                            let msg = format!("import `{}` conflicts with type in \
-                                               this module",
-                                              &token::get_name(name));
-                            span_err!(self.session, import_span, E0256, "{}", &msg[..]);
-                            if let Some(span) = ty.type_span {
-                                self.session.span_note(span,
-                                                       "note conflicting type here")
-                            }
-                        }
-                        Some(ref module_def) => {
-                            match module_def.kind.get() {
-                                ImplModuleKind => {
-                                    if let Some(span) = ty.type_span {
-                                        let msg = format!("inherent implementations \
-                                                           are only allowed on types \
-                                                           defined in the current module");
-                                        span_err!(self.session, span, E0257, "{}", &msg[..]);
-                                        self.session.span_note(import_span,
-                                                               "import from other module here")
-                                    }
-                                }
-                                _ => {
-                                    let msg = format!("import `{}` conflicts with existing \
-                                                       submodule",
-                                                      &token::get_name(name));
-                                    span_err!(self.session, import_span, E0258, "{}", &msg[..]);
-                                    if let Some(span) = ty.type_span {
-                                        self.session.span_note(span,
-                                                               "note conflicting module here")
-                                    }
-                                }
-                            }
-                        }
+                    let (what, note) = if ty.module_def.is_some() {
+                        ("existing submodule", "note conflicting module here")
+                    } else {
+                        ("type in this module", "note conflicting type here")
+                    };
+                    span_err!(self.session, import_span, E0256,
+                              "import `{}` conflicts with {}",
+                              &token::get_name(name), what);
+                    if let Some(span) = ty.type_span {
+                        self.session.span_note(span, note);
                     }
                 }
             }
@@ -2267,7 +2239,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             return Failed(None);
                         }
                         TraitModuleKind |
-                        ImplModuleKind |
                         EnumModuleKind |
                         TypeModuleKind |
                         AnonymousModuleKind => {
@@ -2365,7 +2336,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     match new_module.kind.get() {
                         NormalModuleKind => return Some(new_module),
                         TraitModuleKind |
-                        ImplModuleKind |
                         EnumModuleKind |
                         TypeModuleKind |
                         AnonymousModuleKind => module_ = new_module,
@@ -2382,7 +2352,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         match module_.kind.get() {
             NormalModuleKind => return module_,
             TraitModuleKind |
-            ImplModuleKind |
             EnumModuleKind |
             TypeModuleKind |
             AnonymousModuleKind => {
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 488d9d53dbe..7ef2db2c28d 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -15,6 +15,7 @@ use check::{FnCtxt};
 use check::vtable;
 use check::vtable::select_new_fcx_obligations;
 use middle::def;
+use middle::privacy::{AllPublic, DependsOn, LastPrivate, LastMod};
 use middle::subst;
 use middle::traits;
 use middle::ty::*;
@@ -309,16 +310,22 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                               method_name: ast::Name,
                               self_ty: Ty<'tcx>,
                               expr_id: ast::NodeId)
-                              -> Result<def::Def, MethodError>
+                              -> Result<(def::Def, LastPrivate), MethodError>
 {
     let mode = probe::Mode::Path;
     let pick = try!(probe::probe(fcx, span, mode, method_name, self_ty, expr_id));
     let def_id = pick.method_ty.def_id;
+    let mut lp = LastMod(AllPublic);
     let provenance = match pick.kind {
-        probe::InherentImplPick(impl_def_id) => def::FromImpl(impl_def_id),
+        probe::InherentImplPick(impl_def_id) => {
+            if pick.method_ty.vis != ast::Public {
+                lp = LastMod(DependsOn(def_id));
+            }
+            def::FromImpl(impl_def_id)
+        }
         _ => def::FromTrait(pick.method_ty.container.id())
     };
-    Ok(def::DefMethod(def_id, provenance))
+    Ok((def::DefMethod(def_id, provenance), lp))
 }
 
 
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 938b7edeef2..f24da78bc7d 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -281,6 +281,11 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             ty::ty_closure(did, _, _) => {
                 self.assemble_inherent_impl_candidates_for_type(did);
             }
+            ty::ty_uniq(_) => {
+                if let Some(box_did) = self.tcx().lang_items.owned_box() {
+                    self.assemble_inherent_impl_candidates_for_type(box_did);
+                }
+            }
             ty::ty_param(p) => {
                 self.assemble_inherent_candidates_from_param(self_ty, p);
             }
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index f5a03f0721a..9832fe1cb6e 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -33,7 +33,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                               span: Span,
                               rcvr_ty: Ty<'tcx>,
                               method_name: ast::Name,
-                              callee_expr: &ast::Expr,
+                              rcvr_expr: Option<&ast::Expr>,
                               error: MethodError)
 {
     // avoid suggestions when we don't know what's going on.
@@ -46,16 +46,6 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             let cx = fcx.tcx();
             let method_ustring = method_name.user_string(cx);
 
-            // True if the type is a struct and contains a field with
-            // the same name as the not-found method
-            let is_field = match rcvr_ty.sty {
-                ty::ty_struct(did, _) =>
-                    ty::lookup_struct_fields(cx, did)
-                        .iter()
-                        .any(|f| f.name.user_string(cx) == method_ustring),
-                _ => false
-            };
-
             fcx.type_error_message(
                 span,
                 |actual| {
@@ -68,10 +58,13 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 None);
 
             // If the method has the name of a field, give a help note
-            if is_field {
-                cx.sess.span_note(span,
-                    &format!("use `(s.{0})(...)` if you meant to call the \
-                            function stored in the `{0}` field", method_ustring));
+            if let (&ty::ty_struct(did, _), Some(_)) = (&rcvr_ty.sty, rcvr_expr) {
+                let fields = ty::lookup_struct_fields(cx, did);
+                if fields.iter().any(|f| f.name == method_name) {
+                    cx.sess.span_note(span,
+                        &format!("use `(s.{0})(...)` if you meant to call the \
+                                 function stored in the `{0}` field", method_ustring));
+                }
             }
 
             if static_sources.len() > 0 {
@@ -82,7 +75,8 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 report_candidates(fcx, span, method_name, static_sources);
             }
 
-            suggest_traits_to_import(fcx, span, rcvr_ty, method_name, out_of_scope_traits)
+            suggest_traits_to_import(fcx, span, rcvr_ty, method_name,
+                                     rcvr_expr, out_of_scope_traits)
         }
 
         MethodError::Ambiguity(sources) => {
@@ -93,15 +87,18 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
 
         MethodError::ClosureAmbiguity(trait_def_id) => {
-            fcx.sess().span_err(
-                span,
-                &*format!("the `{}` method from the `{}` trait cannot be explicitly \
-                           invoked on this closure as we have not yet inferred what \
-                           kind of closure it is; use overloaded call notation instead \
-                           (e.g., `{}()`)",
-                          method_name.user_string(fcx.tcx()),
-                          ty::item_path_str(fcx.tcx(), trait_def_id),
-                          pprust::expr_to_string(callee_expr)));
+            let msg = format!("the `{}` method from the `{}` trait cannot be explicitly \
+                               invoked on this closure as we have not yet inferred what \
+                               kind of closure it is",
+                               method_name.user_string(fcx.tcx()),
+                               ty::item_path_str(fcx.tcx(), trait_def_id));
+            let msg = if let Some(callee) = rcvr_expr {
+                format!("{}; use overloaded call notation instead (e.g., `{}()`)",
+                        msg, pprust::expr_to_string(callee))
+            } else {
+                msg
+            };
+            fcx.sess().span_err(span, &msg);
         }
     }
 
@@ -156,6 +153,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                       span: Span,
                                       rcvr_ty: Ty<'tcx>,
                                       method_name: ast::Name,
+                                      rcvr_expr: Option<&ast::Expr>,
                                       valid_out_of_scope_traits: Vec<ast::DefId>)
 {
     let tcx = fcx.tcx();
@@ -184,7 +182,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         return
     }
 
-    let type_is_local = type_derefs_to_local(fcx, span, rcvr_ty);
+    let type_is_local = type_derefs_to_local(fcx, span, rcvr_ty, rcvr_expr);
 
     // there's no implemented traits, so lets suggest some traits to
     // implement, by finding ones that have the method name, and are
@@ -233,33 +231,39 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 /// autoderefs of `rcvr_ty`.
 fn type_derefs_to_local<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   span: Span,
-                                  rcvr_ty: Ty<'tcx>) -> bool {
-    check::autoderef(fcx, span, rcvr_ty, None,
-                     check::UnresolvedTypeAction::Ignore, check::NoPreference,
-                     |&: ty, _| {
-        let is_local = match ty.sty {
+                                  rcvr_ty: Ty<'tcx>,
+                                  rcvr_expr: Option<&ast::Expr>) -> bool {
+    fn is_local(ty: Ty) -> bool {
+        match ty.sty {
             ty::ty_enum(did, _) | ty::ty_struct(did, _) => ast_util::is_local(did),
 
             ty::ty_trait(ref tr) => ast_util::is_local(tr.principal_def_id()),
 
             ty::ty_param(_) => true,
 
-            // the user cannot implement traits for unboxed closures, so
-            // there's no point suggesting anything at all, local or not.
-            ty::ty_closure(..) => return Some(false),
-
             // everything else (primitive types etc.) is effectively
             // non-local (there are "edge" cases, e.g. (LocalType,), but
             // the noise from these sort of types is usually just really
             // annoying, rather than any sort of help).
             _ => false
-        };
-        if is_local {
-            Some(true)
+        }
+    }
+
+    // This occurs for UFCS desugaring of `T::method`, where there is no
+    // receiver expression for the method call, and thus no autoderef.
+    if rcvr_expr.is_none() {
+        return is_local(fcx.resolve_type_vars_if_possible(rcvr_ty));
+    }
+
+    check::autoderef(fcx, span, rcvr_ty, None,
+                     check::UnresolvedTypeAction::Ignore, check::NoPreference,
+                     |ty, _| {
+        if is_local(ty) {
+            Some(())
         } else {
             None
         }
-    }).2.unwrap_or(false)
+    }).2.is_some()
 }
 
 #[derive(Copy)]
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 7a4fab5e56c..068e03dab12 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -91,6 +91,7 @@ use middle::infer;
 use middle::mem_categorization as mc;
 use middle::mem_categorization::McResult;
 use middle::pat_util::{self, pat_id_map};
+use middle::privacy::{AllPublic, LastMod};
 use middle::region::{self, CodeExtent};
 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
 use middle::traits;
@@ -2687,7 +2688,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
             }
             Err(error) => {
                 method::report_error(fcx, method_name.span, expr_t,
-                                     method_name.node.name, rcvr, error);
+                                     method_name.node.name, Some(rcvr), error);
                 fcx.write_error(expr.id);
                 fcx.tcx().types.err
             }
@@ -3598,8 +3599,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
           };
 
           // Helpers to avoid keeping the RefCell borrow for too long.
-          let get_def = |&:| tcx.def_map.borrow().get(&id).cloned();
-          let get_partial_def = |&:| tcx.partial_def_map.borrow().get(&id).cloned();
+          let get_def = || tcx.def_map.borrow().get(&id).cloned();
+          let get_partial_def = || tcx.partial_def_map.borrow().get(&id).cloned();
 
           if let Some(def) = get_def() {
               let (scheme, predicates) =
@@ -3621,10 +3622,16 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
               let method_segment = path.segments.last().unwrap();
               let method_name = method_segment.identifier.name;
               match method::resolve_ufcs(fcx, expr.span, method_name, ty, id) {
-                  Ok(def) => {
+                  Ok((def, lp)) => {
                       // Write back the new resolution.
                       tcx.def_map.borrow_mut().insert(id, def);
 
+                      if let LastMod(AllPublic) = lp {
+                          // Public method, don't change the last private entry.
+                      } else {
+                          tcx.last_private_map.borrow_mut().insert(id, lp);
+                      }
+
                       let (scheme, predicates) =
                           type_scheme_and_predicates_for_def(fcx, expr.span, def);
                       instantiate_path(fcx, slice::ref_slice(method_segment),
@@ -3633,7 +3640,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                   }
                   Err(error) => {
                       method::report_error(fcx, expr.span, ty,
-                                           method_name, expr, error);
+                                           method_name, None, error);
                       fcx.write_error(id);
                   }
               }
@@ -4842,9 +4849,9 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
     }
     if let Some(self_ty) = opt_self_ty {
-        // `<T as Trait>::foo` shouldn't have resolved to a `Self`-less item.
-        assert_eq!(type_defs.len(subst::SelfSpace), 1);
-        substs.types.push(subst::SelfSpace, self_ty);
+        if type_defs.len(subst::SelfSpace) == 1 {
+            substs.types.push(subst::SelfSpace, self_ty);
+        }
     }
 
     // Now we have to compare the types that the user *actually*
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index d34a16a924f..34fadc70af8 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -15,8 +15,8 @@ use middle::traits;
 use middle::ty;
 use syntax::ast::{Item, ItemImpl};
 use syntax::ast;
+use syntax::ast_map;
 use syntax::ast_util;
-use syntax::codemap::Span;
 use syntax::visit;
 use util::ppaux::{Repr, UserString};
 
@@ -30,9 +30,9 @@ struct OrphanChecker<'cx, 'tcx:'cx> {
 }
 
 impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
-    fn check_def_id(&self, span: Span, def_id: ast::DefId) {
+    fn check_def_id(&self, item: &ast::Item, def_id: ast::DefId) {
         if def_id.krate != ast::LOCAL_CRATE {
-            span_err!(self.tcx.sess, span, E0116,
+            span_err!(self.tcx.sess, item.span, E0116,
                       "cannot associate methods with a type outside the \
                        crate the type is defined in; define and implement \
                        a trait or new type instead");
@@ -41,7 +41,7 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
 }
 
 impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &'v ast::Item) {
+    fn visit_item(&mut self, item: &ast::Item) {
         let def_id = ast_util::local_def(item.id);
         match item.node {
             ast::ItemImpl(_, _, _, None, _, _) => {
@@ -52,15 +52,13 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
                 match self_ty.sty {
                     ty::ty_enum(def_id, _) |
                     ty::ty_struct(def_id, _) => {
-                        self.check_def_id(item.span, def_id);
+                        self.check_def_id(item, def_id);
                     }
                     ty::ty_trait(ref data) => {
-                        self.check_def_id(item.span, data.principal_def_id());
+                        self.check_def_id(item, data.principal_def_id());
                     }
                     ty::ty_uniq(..) => {
-                        self.check_def_id(item.span,
-                                          self.tcx.lang_items.owned_box()
-                                              .unwrap());
+                        self.check_def_id(item, self.tcx.lang_items.owned_box().unwrap());
                     }
                     _ => {
                         span_err!(self.tcx.sess, item.span, E0118,
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 6f363faef60..7b43a9fef06 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -80,6 +80,7 @@ register_diagnostics! {
     E0120,
     E0121,
     E0122,
+    E0123,
     E0124,
     E0127,
     E0128,
diff --git a/src/test/compile-fail/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs
index 3e02a11c378..7a7406115d3 100644
--- a/src/test/compile-fail/bad-mid-path-type-params.rs
+++ b/src/test/compile-fail/bad-mid-path-type-params.rs
@@ -43,7 +43,7 @@ fn foo<'a>() {
     //~^ ERROR too many type parameters provided
 
     let _ = S::<'a,isize>::new::<f64>(1, 1.0);
-    //~^ ERROR too many lifetime parameters provided
+    //~^ ERROR wrong number of lifetime parameters
 
     let _: S2 = Trait::new::<isize,f64>(1, 1.0);
     //~^ ERROR too many type parameters provided
diff --git a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
index 9fea5e609d1..5fa429445a3 100644
--- a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
@@ -19,5 +19,5 @@ impl<A, B, C = (A, B)> Foo<A, B, C> {
 
 fn main() {
     Foo::<isize>::new();
-    //~^ ERROR too few type parameters provided
+    //~^ ERROR wrong number of type arguments
 }
diff --git a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
index 73c19aa012d..d3babb8982d 100644
--- a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
@@ -21,5 +21,5 @@ impl<T, A = Heap> Vec<T, A> {
 
 fn main() {
     Vec::<isize, Heap, bool>::new();
-    //~^ ERROR too many type parameters provided
+    //~^ ERROR wrong number of type arguments
 }
diff --git a/src/test/compile-fail/impl-duplicate-methods.rs b/src/test/compile-fail/impl-duplicate-methods.rs
index c6ce4d04e10..c0c951dd8b1 100644
--- a/src/test/compile-fail/impl-duplicate-methods.rs
+++ b/src/test/compile-fail/impl-duplicate-methods.rs
@@ -11,7 +11,7 @@
 struct Foo;
 impl Foo {
     fn orange(&self){}
-    fn orange(&self){}   //~ ERROR error: duplicate definition of value `orange`
+    fn orange(&self){}   //~ ERROR error: duplicate method in trait impl
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-14254.rs b/src/test/compile-fail/issue-14254.rs
index 74eea0c57a0..ce5fa1f1fe1 100644
--- a/src/test/compile-fail/issue-14254.rs
+++ b/src/test/compile-fail/issue-14254.rs
@@ -29,7 +29,7 @@ impl Foo for *const BarTy {
         baz();
         //~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
         a;
-        //~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
+        //~^ ERROR: unresolved name `a`
     }
 }
 
@@ -42,11 +42,11 @@ impl<'a> Foo for &'a BarTy {
         y;
         //~^ ERROR: unresolved name `y`. Did you mean `self.y`?
         a;
-        //~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
+        //~^ ERROR: unresolved name `a`
         bah;
         //~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
         b;
-        //~^ ERROR: unresolved name `b`. Did you mean to call `self.b`?
+        //~^ ERROR: unresolved name `b`
     }
 }
 
@@ -59,11 +59,11 @@ impl<'a> Foo for &'a mut BarTy {
         y;
         //~^ ERROR: unresolved name `y`. Did you mean `self.y`?
         a;
-        //~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
+        //~^ ERROR: unresolved name `a`
         bah;
         //~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
         b;
-        //~^ ERROR: unresolved name `b`. Did you mean to call `self.b`?
+        //~^ ERROR: unresolved name `b`
     }
 }
 
diff --git a/src/test/compile-fail/issue-21202.rs b/src/test/compile-fail/issue-21202.rs
index 5c1de6dfc55..05485008e51 100644
--- a/src/test/compile-fail/issue-21202.rs
+++ b/src/test/compile-fail/issue-21202.rs
@@ -18,7 +18,7 @@ mod B {
     use crate1::A::Foo;
     fn bar(f: Foo) {
         Foo::foo(&f);
-        //~^ ERROR: function `foo` is private
+        //~^ ERROR: method `foo` is private
     }
 }
 
diff --git a/src/test/compile-fail/issue-2356.rs b/src/test/compile-fail/issue-2356.rs
index f0ae0eb59f5..48cc27e2289 100644
--- a/src/test/compile-fail/issue-2356.rs
+++ b/src/test/compile-fail/issue-2356.rs
@@ -36,7 +36,7 @@ impl Groom for cat {
     shave(4);
     //~^ ERROR: unresolved name `shave`. Did you mean to call `Groom::shave`?
     purr();
-    //~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
+    //~^ ERROR: unresolved name `purr`
   }
 }
 
@@ -45,13 +45,13 @@ impl cat {
 
     fn purr_louder() {
         static_method();
-        //~^ ERROR: unresolved name `static_method`. Did you mean to call `cat::static_method`
+        //~^ ERROR: unresolved name `static_method`
         purr();
-        //~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
+        //~^ ERROR: unresolved name `purr`
         purr();
-        //~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
+        //~^ ERROR: unresolved name `purr`
         purr();
-        //~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
+        //~^ ERROR: unresolved name `purr`
     }
 }
 
@@ -65,7 +65,7 @@ impl cat {
 
   fn purr(&self) {
     grow_older();
-    //~^ ERROR: unresolved name `grow_older`. Did you mean to call `cat::grow_older`
+    //~^ ERROR: unresolved name `grow_older`
     shave();
     //~^ ERROR: unresolved name `shave`
   }
@@ -79,7 +79,7 @@ impl cat {
     whiskers = 4;
     //~^ ERROR: unresolved name `whiskers`. Did you mean `self.whiskers`?
     purr_louder();
-    //~^ ERROR: unresolved name `purr_louder`. Did you mean to call `cat::purr_louder`
+    //~^ ERROR: unresolved name `purr_louder`
   }
 }
 
diff --git a/src/test/compile-fail/issue-4265.rs b/src/test/compile-fail/issue-4265.rs
index b4bc7ecdc5f..ab18e0bcddc 100644
--- a/src/test/compile-fail/issue-4265.rs
+++ b/src/test/compile-fail/issue-4265.rs
@@ -17,7 +17,7 @@ impl Foo {
         Foo { baz: 0 }.bar();
     }
 
-    fn bar() { //~ ERROR duplicate definition of value `bar`
+    fn bar() { //~ ERROR duplicate method in trait impl
     }
 }
 
diff --git a/src/test/compile-fail/method-macro-backtrace.rs b/src/test/compile-fail/method-macro-backtrace.rs
index f4740492651..c9ef2df8e13 100644
--- a/src/test/compile-fail/method-macro-backtrace.rs
+++ b/src/test/compile-fail/method-macro-backtrace.rs
@@ -29,7 +29,7 @@ impl S {
 
     // Cause an error. It shouldn't have any macro backtrace frames.
     fn bar(&self) { }
-    fn bar(&self) { } //~ ERROR duplicate definition
+    fn bar(&self) { } //~ ERROR duplicate method
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/trait-or-new-type-instead.rs b/src/test/compile-fail/trait-or-new-type-instead.rs
index 047e4e50c82..3aec23a55b8 100644
--- a/src/test/compile-fail/trait-or-new-type-instead.rs
+++ b/src/test/compile-fail/trait-or-new-type-instead.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// FIXME(eddyb/UFCS) This should have a nicer error, but that's not possible just yet.
-impl<T> Option<T> { //~ ERROR use of undeclared type name `Option`
+impl<T> Option<T> {
+//~^ ERROR cannot associate methods with a type outside the crate the type is defined in
     pub fn foo(&self) { }
 }
 
diff --git a/src/test/compile-fail/use-from-trait.rs b/src/test/compile-fail/use-from-trait.rs
index 2a97155dd2e..49d8622976b 100644
--- a/src/test/compile-fail/use-from-trait.rs
+++ b/src/test/compile-fail/use-from-trait.rs
@@ -11,7 +11,7 @@
 use Trait::foo;
 //~^ ERROR `foo` is not directly importable
 use Foo::new;
-//~^ ERROR `new` is not directly importable
+//~^ ERROR unresolved import `Foo::new`. Not a module `Foo`
 
 pub trait Trait {
     fn foo();
diff --git a/src/test/compile-fail/trait-impl-2.rs b/src/test/run-pass/impl-not-adjacent-to-type.rs
index 303e3d93744..c1dc68b2456 100644
--- a/src/test/compile-fail/trait-impl-2.rs
+++ b/src/test/run-pass/impl-not-adjacent-to-type.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,17 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test calling methods on an impl for a bare trait. This test checks trait impls
-// must be in the same module as the trait.
-
-mod Foo {
-    trait T {}
+mod foo {
+    pub struct Point {
+        pub x: i32,
+        pub y: i32,
+    }
 }
 
-mod Bar {
-    impl<'a> ::Foo::T+'a { //~ERROR: inherent implementations may only be implemented in the same
-        fn foo(&self) {}
-    }
+impl foo::Point {
+    fn x(&self) -> i32 { self.x }
 }
 
-fn main() {}
+fn main() {
+    assert_eq!((foo::Point { x: 1, y: 3}).x(), 1);
+}
diff --git a/src/test/compile-fail/impl-not-adjacent-to-type.rs b/src/test/run-pass/trait-impl-2.rs
index 7a7673d871d..727c33d6ce5 100644
--- a/src/test/compile-fail/impl-not-adjacent-to-type.rs
+++ b/src/test/run-pass/trait-impl-2.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,17 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-mod foo {
-    pub struct Foo {
-        x: isize,
-        y: isize,
+mod Foo {
+    trait Trait {
+        fn foo(&self);
     }
 }
 
-impl foo::Foo {
-//~^ ERROR implementations may only be implemented in the same module
-    fn bar() {}
+mod Bar {
+    impl<'a> ::Foo::Trait+'a {
+        fn bar(&self) { self.foo() }
+    }
 }
 
 fn main() {}
-