parent
10d99a9734
commit
d06b7057cf
6 changed files with 50 additions and 18 deletions
|
@ -1272,9 +1272,9 @@ pub fn each_impl<F>(cdata: Cmd, mut callback: F) where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn each_implementation_for_type<F>(cdata: Cmd,
|
pub fn each_implementation_for_type<F>(cdata: Cmd,
|
||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
mut callback: F) where
|
mut callback: F)
|
||||||
F: FnMut(ast::DefId),
|
where F: FnMut(ast::DefId),
|
||||||
{
|
{
|
||||||
let item_doc = lookup_item(id, cdata.data());
|
let item_doc = lookup_item(id, cdata.data());
|
||||||
reader::tagged_docs(item_doc,
|
reader::tagged_docs(item_doc,
|
||||||
|
|
|
@ -1222,8 +1222,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
encode_attributes(rbml_w, item.attrs[]);
|
encode_attributes(rbml_w, item.attrs[]);
|
||||||
encode_unsafety(rbml_w, unsafety);
|
encode_unsafety(rbml_w, unsafety);
|
||||||
match ty.node {
|
match ty.node {
|
||||||
ast::TyPath(ref path, _) if path.segments
|
ast::TyPath(ref path, _) if path.segments.len() == 1 => {
|
||||||
.len() == 1 => {
|
|
||||||
let ident = path.segments.last().unwrap().identifier;
|
let ident = path.segments.last().unwrap().identifier;
|
||||||
encode_impl_type_basename(rbml_w, ident);
|
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 the implementations of this trait.
|
||||||
encode_extension_implementations(ecx, rbml_w, def_id);
|
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();
|
rbml_w.end_tag();
|
||||||
|
|
||||||
// Now output the trait item info for each trait item.
|
// Now output the trait item info for each trait item.
|
||||||
|
@ -1452,9 +1454,6 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
|
|
||||||
rbml_w.end_tag();
|
rbml_w.end_tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode inherent implementations for this trait.
|
|
||||||
encode_inherent_implementations(ecx, rbml_w, def_id);
|
|
||||||
}
|
}
|
||||||
ast::ItemMac(..) => {
|
ast::ItemMac(..) => {
|
||||||
// macros are encoded separately
|
// macros are encoded separately
|
||||||
|
|
|
@ -128,7 +128,7 @@ impl ImplOrTraitItemContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone, Show)]
|
||||||
pub enum ImplOrTraitItem<'tcx> {
|
pub enum ImplOrTraitItem<'tcx> {
|
||||||
MethodTraitItem(Rc<Method<'tcx>>),
|
MethodTraitItem(Rc<Method<'tcx>>),
|
||||||
TypeTraitItem(Rc<AssociatedType>),
|
TypeTraitItem(Rc<AssociatedType>),
|
||||||
|
@ -173,7 +173,7 @@ impl<'tcx> ImplOrTraitItem<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Copy)]
|
#[deriving(Clone, Copy, Show)]
|
||||||
pub enum ImplOrTraitItemId {
|
pub enum ImplOrTraitItemId {
|
||||||
MethodTraitItemId(ast::DefId),
|
MethodTraitItemId(ast::DefId),
|
||||||
TypeTraitItemId(ast::DefId),
|
TypeTraitItemId(ast::DefId),
|
||||||
|
@ -232,7 +232,7 @@ impl<'tcx> Method<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Copy)]
|
#[deriving(Clone, Copy, Show)]
|
||||||
pub struct AssociatedType {
|
pub struct AssociatedType {
|
||||||
pub name: ast::Name,
|
pub name: ast::Name,
|
||||||
pub vis: ast::Visibility,
|
pub vis: ast::Visibility,
|
||||||
|
@ -4931,10 +4931,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
|
/// Helper for looking things up in the various maps that are populated during
|
||||||
/// (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of these share the pattern that if the
|
/// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of
|
||||||
/// id is local, it should have been loaded into the map by the `typeck::collect` phase. If the
|
/// these share the pattern that if the id is local, it should have been loaded
|
||||||
/// def-id is external, then we have to go consult the crate loading code (and cache the result for
|
/// 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).
|
/// the future).
|
||||||
fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
|
fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
|
||||||
def_id: ast::DefId,
|
def_id: ast::DefId,
|
||||||
|
@ -5973,11 +5974,12 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("populate_implementations_for_type_if_necessary: searching for {}", type_id);
|
||||||
|
|
||||||
let mut inherent_impls = Vec::new();
|
let mut inherent_impls = Vec::new();
|
||||||
csearch::each_implementation_for_type(&tcx.sess.cstore, type_id,
|
csearch::each_implementation_for_type(&tcx.sess.cstore, type_id,
|
||||||
|impl_def_id| {
|
|impl_def_id| {
|
||||||
let impl_items = csearch::get_impl_items(&tcx.sess.cstore,
|
let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id);
|
||||||
impl_def_id);
|
|
||||||
|
|
||||||
// Record the trait->implementation mappings, if applicable.
|
// Record the trait->implementation mappings, if applicable.
|
||||||
let associated_traits = csearch::get_impl_trait(tcx, impl_def_id);
|
let associated_traits = csearch::get_impl_trait(tcx, impl_def_id);
|
||||||
|
|
|
@ -267,6 +267,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||||
return; // already visited
|
return; // already visited
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("assemble_inherent_impl_probe {}", impl_def_id);
|
||||||
|
|
||||||
let method = match impl_method(self.tcx(), impl_def_id, self.method_name) {
|
let method = match impl_method(self.tcx(), impl_def_id, self.method_name) {
|
||||||
Some(m) => m,
|
Some(m) => m,
|
||||||
None => { return; } // No method with correct name on this impl
|
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,
|
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={}",
|
debug!("assemble_extension_candidates_for_trait: trait_def_id={}",
|
||||||
trait_def_id.repr(self.tcx()));
|
trait_def_id.repr(self.tcx()));
|
||||||
|
|
||||||
|
@ -983,6 +985,7 @@ fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||||
-> Option<(uint, Rc<ty::Method<'tcx>>)>
|
-> Option<(uint, Rc<ty::Method<'tcx>>)>
|
||||||
{
|
{
|
||||||
let trait_items = ty::trait_items(tcx, trait_def_id);
|
let trait_items = ty::trait_items(tcx, trait_def_id);
|
||||||
|
debug!("trait_method; items: {}", trait_items);
|
||||||
trait_items
|
trait_items
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|item|
|
.filter(|item|
|
||||||
|
|
17
src/test/auxiliary/traitimpl.rs
Normal file
17
src/test/auxiliary/traitimpl.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test inherant trait impls work cross-crait.
|
||||||
|
|
||||||
|
pub trait Bar<'a> for ?Sized : 'a {}
|
||||||
|
|
||||||
|
impl<'a> Bar<'a> {
|
||||||
|
pub fn bar(&self) {}
|
||||||
|
}
|
|
@ -10,6 +10,10 @@
|
||||||
|
|
||||||
// Test calling methods on an impl for a bare trait.
|
// 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;
|
static mut COUNT: uint = 1;
|
||||||
|
|
||||||
trait T {}
|
trait T {}
|
||||||
|
@ -25,6 +29,9 @@ impl<'a> T+'a {
|
||||||
|
|
||||||
impl T for int {}
|
impl T for int {}
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
impl<'a> Bar<'a> for Foo {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x: &T = &42i;
|
let x: &T = &42i;
|
||||||
|
|
||||||
|
@ -33,4 +40,8 @@ fn main() {
|
||||||
T::bar();
|
T::bar();
|
||||||
|
|
||||||
unsafe { assert!(COUNT == 12); }
|
unsafe { assert!(COUNT == 12); }
|
||||||
|
|
||||||
|
// Cross-crait case
|
||||||
|
let x: &Bar = &Foo;
|
||||||
|
x.bar();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue