diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 70325294743e8..0917135bee9a1 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1275,9 +1275,9 @@ pub fn each_impl(cdata: Cmd, mut callback: F) where } pub fn each_implementation_for_type(cdata: Cmd, - id: ast::NodeId, - mut callback: F) where - F: FnMut(ast::DefId), + id: ast::NodeId, + mut callback: F) + where F: FnMut(ast::DefId), { let item_doc = lookup_item(id, cdata.data()); reader::tagged_docs(item_doc, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 8378c620c1d19..10383b901f38a 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1222,8 +1222,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_attributes(rbml_w, item.attrs[]); encode_unsafety(rbml_w, unsafety); match ty.node { - ast::TyPath(ref path, _) if path.segments - .len() == 1 => { + ast::TyPath(ref path, _) if path.segments.len() == 1 => { let ident = path.segments.last().unwrap().identifier; encode_impl_type_basename(rbml_w, ident); } @@ -1351,6 +1350,9 @@ fn encode_info_for_item(ecx: &EncodeContext, // Encode the implementations of this trait. encode_extension_implementations(ecx, rbml_w, def_id); + // Encode inherent implementations for this trait. + encode_inherent_implementations(ecx, rbml_w, def_id); + rbml_w.end_tag(); // Now output the trait item info for each trait item. @@ -1453,9 +1455,6 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } - - // Encode inherent implementations for this trait. - encode_inherent_implementations(ecx, rbml_w, def_id); } ast::ItemMac(..) => { // macros are encoded separately diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 07ff0ed67a64e..e699ee2ec9145 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -128,7 +128,7 @@ impl ImplOrTraitItemContainer { } } -#[deriving(Clone)] +#[deriving(Clone, Show)] pub enum ImplOrTraitItem<'tcx> { MethodTraitItem(Rc>), TypeTraitItem(Rc), @@ -173,7 +173,7 @@ impl<'tcx> ImplOrTraitItem<'tcx> { } } -#[deriving(Clone, Copy)] +#[deriving(Clone, Copy, Show)] pub enum ImplOrTraitItemId { MethodTraitItemId(ast::DefId), TypeTraitItemId(ast::DefId), @@ -232,7 +232,7 @@ impl<'tcx> Method<'tcx> { } } -#[deriving(Clone, Copy)] +#[deriving(Clone, Copy, Show)] pub struct AssociatedType { pub name: ast::Name, pub vis: ast::Visibility, @@ -4960,10 +4960,11 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) } } -/// Helper for looking things up in the various maps that are populated during typeck::collect -/// (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of these share the pattern that if the -/// id is local, it should have been loaded into the map by the `typeck::collect` phase. If the -/// def-id is external, then we have to go consult the crate loading code (and cache the result for +/// Helper for looking things up in the various maps that are populated during +/// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of +/// these share the pattern that if the id is local, it should have been loaded +/// into the map by the `typeck::collect` phase. If the def-id is external, +/// then we have to go consult the crate loading code (and cache the result for /// the future). fn lookup_locally_or_in_crate_store(descr: &str, def_id: ast::DefId, @@ -6034,11 +6035,12 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt, return } + debug!("populate_implementations_for_type_if_necessary: searching for {}", type_id); + let mut inherent_impls = Vec::new(); csearch::each_implementation_for_type(&tcx.sess.cstore, type_id, |impl_def_id| { - let impl_items = csearch::get_impl_items(&tcx.sess.cstore, - impl_def_id); + let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id); // Record the trait->implementation mappings, if applicable. let associated_traits = csearch::get_impl_trait(tcx, impl_def_id); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index f00e3e2d4527a..b8920ffde5895 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -267,6 +267,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { return; // already visited } + debug!("assemble_inherent_impl_probe {}", impl_def_id); + let method = match impl_method(self.tcx(), impl_def_id, self.method_name) { Some(m) => m, None => { return; } // No method with correct name on this impl @@ -432,7 +434,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { } fn assemble_extension_candidates_for_trait(&mut self, - trait_def_id: ast::DefId) { + trait_def_id: ast::DefId) { debug!("assemble_extension_candidates_for_trait: trait_def_id={}", trait_def_id.repr(self.tcx())); @@ -984,6 +986,7 @@ fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>, -> Option<(uint, Rc>)> { let trait_items = ty::trait_items(tcx, trait_def_id); + debug!("trait_method; items: {}", trait_items); trait_items .iter() .filter(|item| diff --git a/src/test/auxiliary/traitimpl.rs b/src/test/auxiliary/traitimpl.rs new file mode 100644 index 0000000000000..fd454509b3940 --- /dev/null +++ b/src/test/auxiliary/traitimpl.rs @@ -0,0 +1,17 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test inherant trait impls work cross-crait. + +pub trait Bar<'a> for ?Sized : 'a {} + +impl<'a> Bar<'a> { + pub fn bar(&self) {} +} diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs index 216a7ef33f54c..003686c0bbefc 100644 --- a/src/test/run-pass/trait-impl.rs +++ b/src/test/run-pass/trait-impl.rs @@ -10,6 +10,10 @@ // Test calling methods on an impl for a bare trait. +// aux-build:traitimpl.rs +extern crate traitimpl; +use traitimpl::Bar; + static mut COUNT: uint = 1; trait T {} @@ -25,6 +29,9 @@ impl<'a> T+'a { impl T for int {} +struct Foo; +impl<'a> Bar<'a> for Foo {} + fn main() { let x: &T = &42i; @@ -33,4 +40,8 @@ fn main() { T::bar(); unsafe { assert!(COUNT == 12); } + + // Cross-crait case + let x: &Bar = &Foo; + x.bar(); }