Skip to content

Cross-crate self as argument method calls #18177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 1, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@ use syntax::parse::token;

use std::collections::hashmap::HashMap;

pub struct StaticMethodInfo {
pub struct MethodInfo {
pub name: ast::Name,
pub def_id: ast::DefId,
pub fn_style: ast::FnStyle,
pub vis: ast::Visibility,
}

Expand Down Expand Up @@ -178,11 +177,11 @@ pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId)
decoder::get_type_name_if_impl(&*cdata, def.node)
}

pub fn get_static_methods_if_impl(cstore: &cstore::CStore,
pub fn get_methods_if_impl(cstore: &cstore::CStore,
def: ast::DefId)
-> Option<Vec<StaticMethodInfo> > {
-> Option<Vec<MethodInfo> > {
let cdata = cstore.get_crate_data(def.krate);
decoder::get_static_methods_if_impl(cstore.intr.clone(), &*cdata, def.node)
decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.node)
}

pub fn get_item_attrs(cstore: &cstore::CStore,
Expand Down
49 changes: 19 additions & 30 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use back::svh::Svh;
use metadata::cstore::crate_metadata;
use metadata::common::*;
use metadata::csearch::StaticMethodInfo;
use metadata::csearch::MethodInfo;
use metadata::csearch;
use metadata::cstore;
use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
Expand Down Expand Up @@ -111,10 +111,9 @@ enum Family {
ImmStatic, // c
MutStatic, // b
Fn, // f
UnsafeFn, // u
CtorFn, // o
StaticMethod, // F
UnsafeStaticMethod, // U
Method, // h
Type, // y
ForeignType, // T
Mod, // m
Expand All @@ -137,10 +136,9 @@ fn item_family(item: rbml::Doc) -> Family {
'c' => ImmStatic,
'b' => MutStatic,
'f' => Fn,
'u' => UnsafeFn,
'o' => CtorFn,
'F' => StaticMethod,
'U' => UnsafeStaticMethod,
'h' => Method,
'y' => Type,
'T' => ForeignType,
'm' => Mod,
Expand Down Expand Up @@ -309,15 +307,9 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
ImmStatic => DlDef(def::DefStatic(did, false)),
MutStatic => DlDef(def::DefStatic(did, true)),
Struct => DlDef(def::DefStruct(did)),
UnsafeFn => DlDef(def::DefFn(did, ast::UnsafeFn, false)),
Fn => DlDef(def::DefFn(did, ast::NormalFn, false)),
CtorFn => DlDef(def::DefFn(did, ast::NormalFn, true)),
StaticMethod | UnsafeStaticMethod => {
let fn_style = if fam == UnsafeStaticMethod {
ast::UnsafeFn
} else {
ast::NormalFn
};
Fn => DlDef(def::DefFn(did, false)),
CtorFn => DlDef(def::DefFn(did, true)),
Method | StaticMethod => {
// def_static_method carries an optional field of its enclosing
// trait or enclosing impl (if this is an inherent static method).
// So we need to detect whether this is in a trait or not, which
Expand All @@ -331,7 +323,12 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
def::FromImpl(item_reqd_and_translated_parent_item(cnum,
item))
};
DlDef(def::DefStaticMethod(did, provenance, fn_style))
match fam {
// We don't bother to get encode/decode the trait id, we don't need it.
Method => DlDef(def::DefMethod(did, None, provenance)),
StaticMethod => DlDef(def::DefStaticMethod(did, provenance)),
_ => panic!()
}
}
Type | ForeignType => DlDef(def::DefTy(did, false)),
Mod => DlDef(def::DefMod(did)),
Expand Down Expand Up @@ -518,7 +515,7 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
None => {}
Some(impl_method_doc) => {
match item_family(impl_method_doc) {
StaticMethod | UnsafeStaticMethod => {
StaticMethod => {
// Hand off the static method
// to the callback.
let static_method_name =
Expand Down Expand Up @@ -905,10 +902,10 @@ pub fn get_type_name_if_impl(cdata: Cmd,
ret
}

pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
cdata: Cmd,
node_id: ast::NodeId)
-> Option<Vec<StaticMethodInfo> > {
-> Option<Vec<MethodInfo> > {
let item = lookup_item(node_id, cdata.data());
if item_family(item) != Impl {
return None;
Expand All @@ -927,31 +924,23 @@ pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
true
});

let mut static_impl_methods = Vec::new();
let mut impl_methods = Vec::new();
for impl_method_id in impl_method_ids.iter() {
let impl_method_doc = lookup_item(impl_method_id.node, cdata.data());
let family = item_family(impl_method_doc);
match family {
StaticMethod | UnsafeStaticMethod => {
let fn_style;
match item_family(impl_method_doc) {
StaticMethod => fn_style = ast::NormalFn,
UnsafeStaticMethod => fn_style = ast::UnsafeFn,
_ => panic!()
}

static_impl_methods.push(StaticMethodInfo {
StaticMethod | Method => {
impl_methods.push(MethodInfo {
name: item_name(&*intr, impl_method_doc),
def_id: item_def_id(impl_method_doc, cdata),
fn_style: fn_style,
vis: item_visibility(impl_method_doc),
});
}
_ => {}
}
}

return Some(static_impl_methods);
return Some(impl_methods);
}

/// If node_id is the constructor of a tuple struct, retrieve the NodeId of
Expand Down
70 changes: 28 additions & 42 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,12 +835,11 @@ fn encode_method_ty_fields(ecx: &EncodeContext,
encode_method_fty(ecx, rbml_w, &method_ty.fty);
encode_visibility(rbml_w, method_ty.vis);
encode_explicit_self(rbml_w, &method_ty.explicit_self);
let fn_style = method_ty.fty.fn_style;
match method_ty.explicit_self {
ty::StaticExplicitSelfCategory => {
encode_family(rbml_w, fn_style_static_method_family(fn_style));
encode_family(rbml_w, STATIC_METHOD_FAMILY);
}
_ => encode_family(rbml_w, style_fn_family(fn_style))
_ => encode_family(rbml_w, METHOD_FAMILY)
}
encode_provided_source(rbml_w, method_ty.provided_source);
}
Expand Down Expand Up @@ -964,20 +963,9 @@ fn encode_inlined_item(ecx: &EncodeContext,
(*eii)(ecx, rbml_w, ii)
}

fn style_fn_family(s: FnStyle) -> char {
match s {
UnsafeFn => 'u',
NormalFn => 'f',
}
}

fn fn_style_static_method_family(s: FnStyle) -> char {
match s {
UnsafeFn => 'U',
NormalFn => 'F',
}
}

const FN_FAMILY: char = 'f';
const STATIC_METHOD_FAMILY: char = 'F';
const METHOD_FAMILY: char = 'h';

fn should_inline(attrs: &[Attribute]) -> bool {
use syntax::attr::*;
Expand Down Expand Up @@ -1081,11 +1069,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_stability(rbml_w, stab);
rbml_w.end_tag();
}
ItemFn(ref decl, fn_style, _, ref generics, _) => {
ItemFn(ref decl, _, _, ref generics, _) => {
add_to_index(item, rbml_w, index);
rbml_w.start_tag(tag_items_data_item);
encode_def_id(rbml_w, def_id);
encode_family(rbml_w, style_fn_family(fn_style));
encode_family(rbml_w, FN_FAMILY);
let tps_len = generics.ty_params.len();
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
encode_name(rbml_w, item.ident.name);
Expand Down Expand Up @@ -1402,13 +1390,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
match method_ty.explicit_self {
ty::StaticExplicitSelfCategory => {
encode_family(rbml_w,
fn_style_static_method_family(
method_ty.fty.fn_style));
STATIC_METHOD_FAMILY);
}
_ => {
encode_family(rbml_w,
style_fn_family(
method_ty.fty.fn_style));
METHOD_FAMILY);
}
}
let pty = ty::lookup_item_type(tcx,
Expand All @@ -1432,30 +1418,30 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_parent_sort(rbml_w, 't');

let trait_item = &ms[i];
match &ms[i] {
&RequiredMethod(ref tm) => {
encode_attributes(rbml_w, tm.attrs.as_slice());
let encode_trait_item = |rbml_w: &mut Encoder| {
// If this is a static method, we've already
// encoded this.
if is_nonstatic_method {
// FIXME: I feel like there is something funny
// going on.
let pty = ty::lookup_item_type(tcx, item_def_id.def_id());
encode_bounds_and_type(rbml_w, ecx, &pty);
}
};
match trait_item {
&RequiredMethod(ref m) => {
encode_attributes(rbml_w, m.attrs.as_slice());
encode_trait_item(rbml_w);
encode_item_sort(rbml_w, 'r');
encode_method_argument_names(rbml_w, &*tm.decl);
encode_method_argument_names(rbml_w, &*m.decl);
}

&ProvidedMethod(ref m) => {
encode_attributes(rbml_w, m.attrs.as_slice());
// If this is a static method, we've already
// encoded this.
if is_nonstatic_method {
// FIXME: I feel like there is something funny
// going on.
let pty = ty::lookup_item_type(tcx,
item_def_id.def_id());
encode_bounds_and_type(rbml_w, ecx, &pty);
}
encode_trait_item(rbml_w);
encode_item_sort(rbml_w, 'p');
encode_inlined_item(ecx,
rbml_w,
IITraitItemRef(def_id, trait_item));
encode_method_argument_names(rbml_w,
&*m.pe_fn_decl());
encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item));
encode_method_argument_names(rbml_w, &*m.pe_fn_decl());
}

&TypeTraitItem(ref associated_type) => {
Expand Down Expand Up @@ -1493,7 +1479,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
encode_visibility(rbml_w, nitem.vis);
match nitem.node {
ForeignItemFn(..) => {
encode_family(rbml_w, style_fn_family(NormalFn));
encode_family(rbml_w, FN_FAMILY);
encode_bounds_and_type(rbml_w, ecx,
&lookup_item_type(ecx.tcx,local_def(nitem.id)));
encode_name(rbml_w, nitem.ident.name);
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,8 @@ fn decode_def(dcx: &DecodeContext, doc: rbml::Doc) -> def::Def {
impl tr for def::Def {
fn tr(&self, dcx: &DecodeContext) -> def::Def {
match *self {
def::DefFn(did, p, is_ctor) => def::DefFn(did.tr(dcx), p, is_ctor),
def::DefStaticMethod(did, wrapped_did2, p) => {
def::DefFn(did, is_ctor) => def::DefFn(did.tr(dcx), is_ctor),
def::DefStaticMethod(did, wrapped_did2) => {
def::DefStaticMethod(did.tr(dcx),
match wrapped_did2 {
def::FromTrait(did2) => {
Expand All @@ -450,8 +450,7 @@ impl tr for def::Def {
def::FromImpl(did2) => {
def::FromImpl(did2.tr(dcx))
}
},
p)
})
}
def::DefMethod(did0, did1, p) => {
def::DefMethod(did0.tr(dcx), did1.map(|did1| did1.tr(dcx)), p)
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use syntax::ast_util::local_def;

#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum Def {
DefFn(ast::DefId, ast::FnStyle, bool /* is_ctor */),
DefStaticMethod(/* method */ ast::DefId, MethodProvenance, ast::FnStyle),
DefFn(ast::DefId, bool /* is_ctor */),
DefStaticMethod(/* method */ ast::DefId, MethodProvenance),
DefSelfTy(/* trait id */ ast::NodeId),
DefMod(ast::DefId),
DefForeignMod(ast::DefId),
Expand Down Expand Up @@ -58,7 +58,7 @@ pub enum MethodProvenance {
impl Def {
pub fn def_id(&self) -> ast::DefId {
match *self {
DefFn(id, _, _) | DefStaticMethod(id, _, _) | DefMod(id) |
DefFn(id, _) | DefStaticMethod(id, _) | DefMod(id) |
DefForeignMod(id) | DefStatic(id, _) |
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
DefTyParam(_, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
match expr.node {
ast::ExprPath(..) => {
match ty::resolve_expr(self.tcx, expr) {
DefFn(did, _, _) if self.def_id_is_transmute(did) => {
DefFn(did, _) if self.def_id_is_transmute(did) => {
let typ = ty::node_id_to_type(self.tcx, expr.id);
match ty::get(typ).sty {
ty_bare_fn(ref bare_fn_ty)
Expand Down
Loading