Skip to content

Commit 5695965

Browse files
committed
Compute a ty::method for methods that appear in impls as well
1 parent 007abe9 commit 5695965

File tree

4 files changed

+89
-79
lines changed

4 files changed

+89
-79
lines changed

src/librustc/metadata/decoder.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -714,18 +714,19 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
714714
tcx: ty::ctxt) -> ty::method
715715
{
716716
let method_doc = lookup_item(id, cdata.data);
717+
let def_id = item_def_id(method_doc, cdata);
718+
let name = item_name(intr, method_doc);
717719
let bounds = item_ty_param_bounds(method_doc, tcx, cdata,
718720
tag_item_method_tps);
719-
let name = item_name(intr, method_doc);
720-
let def_id = item_def_id(method_doc, cdata);
721721
let fty = doc_method_fty(method_doc, tcx, cdata);
722+
let vis = item_visibility(method_doc);
722723
let self_ty = get_self_ty(method_doc);
723724
ty::method {
724725
ident: name,
725726
tps: bounds,
726727
fty: fty,
727728
self_ty: self_ty,
728-
vis: ast::public,
729+
vis: vis,
729730
def_id: def_id
730731
}
731732
}

src/librustc/metadata/encoder.rs

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -562,21 +562,36 @@ fn encode_info_for_struct_ctor(ecx: @EncodeContext,
562562
ebml_w.end_tag();
563563
}
564564

565+
fn encode_method_ty_fields(ecx: @EncodeContext,
566+
ebml_w: writer::Encoder,
567+
method_ty: &ty::method)
568+
{
569+
encode_def_id(ebml_w, method_ty.def_id);
570+
encode_name(ecx, ebml_w, method_ty.ident);
571+
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.tps,
572+
tag_item_method_tps);
573+
encode_method_fty(ecx, ebml_w, &method_ty.fty);
574+
encode_visibility(ebml_w, method_ty.vis);
575+
encode_self_type(ebml_w, method_ty.self_ty);
576+
}
577+
565578
fn encode_info_for_method(ecx: @EncodeContext,
566579
ebml_w: writer::Encoder,
567580
impl_path: &[ast_map::path_elt],
568581
should_inline: bool,
569582
parent_id: node_id,
570583
m: @method,
571-
parent_visibility: ast::visibility,
572584
owner_generics: &ast::Generics,
573585
method_generics: &ast::Generics) {
574586
debug!("encode_info_for_method: %d %s %u %u", m.id,
575587
*ecx.tcx.sess.str_of(m.ident),
576588
owner_generics.ty_params.len(),
577589
method_generics.ty_params.len());
578590
ebml_w.start_tag(tag_items_data_item);
579-
encode_def_id(ebml_w, local_def(m.id));
591+
592+
let method_def_id = local_def(m.id);
593+
let method_ty: @ty::method = ty::method(ecx.tcx, method_def_id);
594+
encode_method_ty_fields(ecx, ebml_w, method_ty);
580595

581596
match m.self_ty.node {
582597
ast::sty_static => {
@@ -592,16 +607,7 @@ fn encode_info_for_method(ecx: @EncodeContext,
592607
encode_type_param_bounds(ebml_w, ecx, &combined_ty_params);
593608

594609
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
595-
encode_name(ecx, ebml_w, m.ident);
596610
encode_path(ecx, ebml_w, impl_path, ast_map::path_name(m.ident));
597-
encode_self_type(ebml_w, m.self_ty.node);
598-
599-
// Combine parent visibility and this visibility.
600-
let visibility = match m.vis {
601-
ast::inherited => parent_visibility,
602-
vis => vis,
603-
};
604-
encode_visibility(ebml_w, visibility);
605611

606612
if len > 0u || should_inline {
607613
(ecx.encode_inlined_item)(
@@ -610,6 +616,7 @@ fn encode_info_for_method(ecx: @EncodeContext,
610616
} else {
611617
encode_symbol(ecx, ebml_w, m.id);
612618
}
619+
613620
ebml_w.end_tag();
614621
}
615622

@@ -863,17 +870,6 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
863870
let mut impl_path = vec::append(~[], path);
864871
impl_path += ~[ast_map::path_name(item.ident)];
865872
866-
// If there is a trait reference, treat the methods as always public.
867-
// This is to work around some incorrect behavior in privacy checking:
868-
// when the method belongs to a trait, it should acquire the privacy
869-
// from the trait, not the impl. Forcing the visibility to be public
870-
// makes things sorta work.
871-
let parent_visibility = if opt_trait.is_some() {
872-
ast::public
873-
} else {
874-
item.vis
875-
};
876-
877873
for methods.each |m| {
878874
index.push(entry {val: m.id, pos: ebml_w.writer.tell()});
879875
encode_info_for_method(ecx,
@@ -882,7 +878,6 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
882878
should_inline(m.attrs),
883879
item.id,
884880
*m,
885-
parent_visibility,
886881
generics,
887882
&m.generics);
888883
}
@@ -909,11 +904,6 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
909904
ebml_w.end_tag();
910905
911906
// Now output the method info for each method.
912-
//
913-
// Note: for the moment, the data structures here are *slightly*
914-
// different from those expected by `encode_info_for_method()`,
915-
// but I do plan to refactor this later in this patch to avoid the
916-
// duplication.
917907
for ty::trait_method_def_ids(tcx, local_def(item.id)).eachi |i, &method_def_id| {
918908
assert!(method_def_id.crate == ast::local_crate);
919909
@@ -923,9 +913,13 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
923913
924914
ebml_w.start_tag(tag_items_data_item);
925915
926-
encode_def_id(ebml_w, method_def_id);
916+
encode_method_ty_fields(ecx, ebml_w, method_ty);
917+
927918
encode_parent_item(ebml_w, local_def(item.id));
928-
encode_name(ecx, ebml_w, method_ty.ident);
919+
920+
let mut trait_path = vec::append(~[], path);
921+
trait_path.push(ast_map::path_name(item.ident));
922+
encode_path(ecx, ebml_w, trait_path, ast_map::path_name(method_ty.ident));
929923
930924
match method_ty.self_ty {
931925
sty_static => {
@@ -946,15 +940,6 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
946940
}
947941
}
948942
949-
encode_ty_type_param_bounds(ebml_w, ecx, method_ty.tps,
950-
tag_item_method_tps);
951-
encode_method_fty(ecx, ebml_w, &method_ty.fty);
952-
encode_visibility(ebml_w, method_ty.vis);
953-
encode_self_type(ebml_w, method_ty.self_ty);
954-
let mut trait_path = vec::append(~[], path);
955-
trait_path.push(ast_map::path_name(item.ident));
956-
encode_path(ecx, ebml_w, trait_path, ast_map::path_name(method_ty.ident));
957-
958943
match ms[i] {
959944
required(_) => {
960945
encode_method_sort(ebml_w, 'r');

src/librustc/middle/typeck/collect.rs

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
315315
ty: ty});
316316
}
317317

318-
319318
fn ty_method_of_trait_method(self: &CrateCtxt,
320319
trait_rp: Option<ty::region_variance>,
321320
trait_generics: &ast::Generics,
@@ -336,8 +335,8 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
336335
AbiSet::Rust(),
337336
&m_generics.lifetimes,
338337
m_decl),
339-
// assume public, because this is only invoked on trait methods
340338
self_ty: m_self_ty.node,
339+
// assume public, because this is only invoked on trait methods
341340
vis: ast::public,
342341
def_id: local_def(*m_id)
343342
}
@@ -599,7 +598,7 @@ pub fn convert_field(ccx: &CrateCtxt,
599598
}
600599

601600
pub struct ConvertedMethod {
602-
mty: ty::method,
601+
mty: @ty::method,
603602
id: ast::node_id,
604603
span: span,
605604
body_id: ast::node_id
@@ -609,13 +608,15 @@ pub fn convert_methods(ccx: &CrateCtxt,
609608
ms: &[@ast::method],
610609
rp: Option<ty::region_variance>,
611610
rcvr_bounds: @~[ty::param_bounds],
612-
rcvr_generics: &ast::Generics)
613-
-> ~[ConvertedMethod] {
614-
611+
rcvr_generics: &ast::Generics,
612+
rcvr_visibility: ast::visibility)
613+
-> ~[ConvertedMethod]
614+
{
615615
let tcx = ccx.tcx;
616-
do vec::map(ms) |m| {
616+
return vec::map(ms, |m| {
617617
let bounds = ty_param_bounds(ccx, &m.generics);
618-
let mty = ty_of_method(ccx, *m, rp, rcvr_generics, &m.generics);
618+
let mty = @ty_of_method(ccx, *m, rp, rcvr_generics,
619+
rcvr_visibility, &m.generics);
619620
let fty = ty::mk_bare_fn(tcx, copy mty.fty);
620621
tcx.tcache.insert(
621622
local_def(m.id),
@@ -628,8 +629,34 @@ pub fn convert_methods(ccx: &CrateCtxt,
628629
ty: fty
629630
});
630631
write_ty_to_tcx(tcx, m.id, fty);
632+
tcx.methods.insert(mty.def_id, mty);
631633
ConvertedMethod {mty: mty, id: m.id,
632634
span: m.span, body_id: m.body.node.id}
635+
});
636+
637+
fn ty_of_method(ccx: &CrateCtxt,
638+
m: @ast::method,
639+
rp: Option<ty::region_variance>,
640+
rcvr_generics: &ast::Generics,
641+
rcvr_visibility: ast::visibility,
642+
method_generics: &ast::Generics) -> ty::method
643+
{
644+
let rscope = MethodRscope::new(m.self_ty.node,
645+
rp,
646+
rcvr_generics);
647+
ty::method {
648+
ident: m.ident,
649+
tps: ty_param_bounds(ccx, &m.generics),
650+
fty: astconv::ty_of_bare_fn(ccx,
651+
&rscope,
652+
m.purity,
653+
ast::RustAbi,
654+
&method_generics.lifetimes,
655+
&m.decl),
656+
self_ty: m.self_ty.node,
657+
vis: m.vis.inherit_from(rcvr_visibility),
658+
def_id: local_def(m.id)
659+
}
633660
}
634661
}
635662

@@ -665,7 +692,7 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
665692
generics,
666693
rp);
667694
}
668-
ast::item_impl(ref generics, trait_ref, selfty, ref ms) => {
695+
ast::item_impl(ref generics, opt_trait_ref, selfty, ref ms) => {
669696
let i_bounds = ty_param_bounds(ccx, generics);
670697
let region_parameterization =
671698
RegionParameterization::from_variance_and_generics(rp, generics);
@@ -677,9 +704,20 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
677704
region_param: rp,
678705
ty: selfty});
679706

680-
// XXX: Bad copy of `ms` below.
681-
let cms = convert_methods(ccx, *ms, rp, i_bounds, generics);
682-
for trait_ref.each |t| {
707+
// If there is a trait reference, treat the methods as always public.
708+
// This is to work around some incorrect behavior in privacy checking:
709+
// when the method belongs to a trait, it should acquire the privacy
710+
// from the trait, not the impl. Forcing the visibility to be public
711+
// makes things sorta work.
712+
let parent_visibility = if opt_trait_ref.is_some() {
713+
ast::public
714+
} else {
715+
it.vis
716+
};
717+
718+
let cms = convert_methods(ccx, *ms, rp, i_bounds, generics,
719+
parent_visibility);
720+
for opt_trait_ref.each |t| {
683721
check_methods_against_trait(ccx, generics, rp, selfty, *t, cms);
684722
}
685723
}
@@ -694,7 +732,8 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
694732
let (_, provided_methods) =
695733
split_trait_methods(*trait_methods);
696734
let (bounds, _) = mk_substs(ccx, generics, rp);
697-
let _ = convert_methods(ccx, provided_methods, rp, bounds, generics);
735+
let _ = convert_methods(ccx, provided_methods, rp, bounds, generics,
736+
it.vis);
698737
}
699738
ast::item_struct(struct_def, ref generics) => {
700739
ensure_no_ty_param_bounds(ccx, it.span, generics, "structure");
@@ -794,30 +833,6 @@ pub fn convert_foreign(ccx: &CrateCtxt, i: @ast::foreign_item) {
794833
ccx.tcx.tcache.insert(local_def(i.id), tpt);
795834
}
796835

797-
pub fn ty_of_method(ccx: &CrateCtxt,
798-
m: @ast::method,
799-
rp: Option<ty::region_variance>,
800-
rcvr_generics: &ast::Generics,
801-
method_generics: &ast::Generics)
802-
-> ty::method {
803-
let rscope = MethodRscope::new(m.self_ty.node,
804-
rp,
805-
rcvr_generics);
806-
ty::method {
807-
ident: m.ident,
808-
tps: ty_param_bounds(ccx, &m.generics),
809-
fty: astconv::ty_of_bare_fn(ccx,
810-
&rscope,
811-
m.purity,
812-
AbiSet::Rust(),
813-
&method_generics.lifetimes,
814-
&m.decl),
815-
self_ty: m.self_ty.node,
816-
vis: m.vis,
817-
def_id: local_def(m.id)
818-
}
819-
}
820-
821836
/*
822837
Instantiates the path for the given trait reference, assuming that
823838
it's bound to a valid trait type. Returns the def_id for the defining

src/libsyntax/ast.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,15 @@ pub struct trait_ref {
11861186
#[deriving(Eq)]
11871187
pub enum visibility { public, private, inherited }
11881188

1189+
impl visibility {
1190+
fn inherit_from(&self, parent_visibility: visibility) -> visibility {
1191+
match self {
1192+
&inherited => parent_visibility,
1193+
&public | &private => *self
1194+
}
1195+
}
1196+
}
1197+
11891198
#[auto_encode]
11901199
#[auto_decode]
11911200
#[deriving(Eq)]

0 commit comments

Comments
 (0)