Skip to content

Commit a8c8e3f

Browse files
committed
auto merge of #16286 : pcwalton/rust/associated-items-groundwork, r=nikomatsakis
methods. This paves the way to associated items by introducing an extra level of abstraction ("impl-or-trait item") between traits/implementations and methods. This new abstraction is encoded in the metadata and used throughout the compiler where appropriate. There are no functional changes; this is purely a refactoring. r? @nick29581
2 parents 404978e + 9907fa4 commit a8c8e3f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1926
-1120
lines changed

src/librustc/front/config.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,14 @@ fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod {
109109

110110
fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
111111
let item = match *item {
112-
ast::ItemImpl(ref a, ref b, c, ref methods) => {
113-
let methods = methods.iter().filter(|m| method_in_cfg(cx, &***m))
114-
.map(|x| *x).collect();
115-
ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
112+
ast::ItemImpl(ref a, ref b, c, ref impl_items) => {
113+
let impl_items = impl_items.iter()
114+
.filter(|ii| {
115+
impl_item_in_cfg(cx, &**ii)
116+
})
117+
.map(|x| *x)
118+
.collect();
119+
ast::ItemImpl((*a).clone(), (*b).clone(), c, impl_items)
116120
}
117121
ast::ItemTrait(ref a, ref b, ref c, ref methods) => {
118122
let methods = methods.iter()
@@ -230,14 +234,16 @@ fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool {
230234
return (cx.in_cfg)(item.attrs.as_slice());
231235
}
232236

233-
fn method_in_cfg(cx: &mut Context, meth: &ast::Method) -> bool {
234-
return (cx.in_cfg)(meth.attrs.as_slice());
237+
fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool {
238+
match *meth {
239+
ast::RequiredMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
240+
ast::ProvidedMethod(meth) => (cx.in_cfg)(meth.attrs.as_slice())
241+
}
235242
}
236243

237-
fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitMethod) -> bool {
238-
match *meth {
239-
ast::Required(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
240-
ast::Provided(meth) => (cx.in_cfg)(meth.attrs.as_slice())
244+
fn impl_item_in_cfg(cx: &mut Context, impl_item: &ast::ImplItem) -> bool {
245+
match *impl_item {
246+
ast::MethodImplItem(meth) => (cx.in_cfg)(meth.attrs.as_slice()),
241247
}
242248
}
243249

src/librustc/lint/builtin.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -801,15 +801,19 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
801801
node: m.id
802802
};
803803

804-
match cx.tcx.methods.borrow().find_copy(&did) {
804+
match cx.tcx.impl_or_trait_items.borrow().find_copy(&did) {
805805
None => cx.sess().span_bug(m.span, "missing method descriptor?!"),
806806
Some(md) => {
807-
match md.container {
808-
ty::TraitContainer(..) => TraitDefaultImpl,
809-
ty::ImplContainer(cid) => {
810-
match ty::impl_trait_ref(cx.tcx, cid) {
811-
Some(..) => TraitImpl,
812-
None => PlainImpl
807+
match md {
808+
ty::MethodTraitItem(md) => {
809+
match md.container {
810+
ty::TraitContainer(..) => TraitDefaultImpl,
811+
ty::ImplContainer(cid) => {
812+
match ty::impl_trait_ref(cx.tcx, cid) {
813+
Some(..) => TraitImpl,
814+
None => PlainImpl
815+
}
816+
}
813817
}
814818
}
815819
}
@@ -1470,7 +1474,15 @@ impl LintPass for Stability {
14701474
trait_id: trait_id,
14711475
method_num: index,
14721476
..
1473-
}) => ty::trait_method(cx.tcx, trait_id, index).def_id
1477+
}) => {
1478+
match ty::trait_item(cx.tcx,
1479+
trait_id,
1480+
index) {
1481+
ty::MethodTraitItem(method) => {
1482+
method.def_id
1483+
}
1484+
}
1485+
}
14741486
}
14751487
}
14761488
None => return

src/librustc/lint/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -563,9 +563,9 @@ impl<'a> Visitor<()> for Context<'a> {
563563
visit::walk_generics(self, g, ());
564564
}
565565

566-
fn visit_trait_method(&mut self, m: &ast::TraitMethod, _: ()) {
566+
fn visit_trait_item(&mut self, m: &ast::TraitItem, _: ()) {
567567
run_lints!(self, check_trait_method, m);
568-
visit::walk_trait_method(self, m, ());
568+
visit::walk_trait_item(self, m, ());
569569
}
570570

571571
fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option<ast::Lifetime>, _: ()) {

src/librustc/lint/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ pub trait LintPass {
141141
fn check_fn(&mut self, _: &Context,
142142
_: &FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
143143
fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { }
144-
fn check_trait_method(&mut self, _: &Context, _: &ast::TraitMethod) { }
144+
fn check_trait_method(&mut self, _: &Context, _: &ast::TraitItem) { }
145145
fn check_struct_def(&mut self, _: &Context,
146146
_: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
147147
fn check_struct_def_post(&mut self, _: &Context,

src/librustc/metadata/common.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub static tag_crate_dep_hash: uint = 0x1e;
7777

7878
pub static tag_mod_impl: uint = 0x1f;
7979

80-
pub static tag_item_trait_method: uint = 0x20;
80+
pub static tag_item_trait_item: uint = 0x20;
8181

8282
pub static tag_item_trait_ref: uint = 0x21;
8383
pub static tag_item_super_trait_ref: uint = 0x22;
@@ -95,14 +95,14 @@ pub static tag_item_field_origin: uint = 0x29;
9595

9696
pub static tag_item_variances: uint = 0x2a;
9797
/*
98-
trait items contain tag_item_trait_method elements,
99-
impl items contain tag_item_impl_method elements, and classes
98+
trait items contain tag_item_trait_item elements,
99+
impl items contain tag_item_impl_item elements, and classes
100100
have both. That's because some code treats classes like traits,
101101
and other code treats them like impls. Because classes can contain
102-
both, tag_item_trait_method and tag_item_impl_method have to be two
102+
both, tag_item_trait_item and tag_item_impl_item have to be two
103103
different tags.
104104
*/
105-
pub static tag_item_impl_method: uint = 0x30;
105+
pub static tag_item_impl_item: uint = 0x30;
106106
pub static tag_item_trait_method_explicit_self: uint = 0x31;
107107

108108

@@ -154,9 +154,11 @@ impl astencode_tag {
154154
}
155155
}
156156

157-
pub static tag_item_trait_method_sort: uint = 0x60;
157+
pub static tag_item_trait_item_sort: uint = 0x60;
158158

159-
pub static tag_item_impl_type_basename: uint = 0x61;
159+
pub static tag_item_trait_parent_sort: uint = 0x61;
160+
161+
pub static tag_item_impl_type_basename: uint = 0x62;
160162

161163
pub static tag_crate_triple: uint = 0x66;
162164

src/librustc/metadata/csearch.rs

+24-20
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use metadata::common::*;
1616
use metadata::cstore;
1717
use metadata::decoder;
1818
use middle::lang_items;
19+
use middle::resolve;
1920
use middle::ty;
2021
use middle::typeck;
2122
use middle::subst::VecPerParamSpace;
@@ -121,30 +122,33 @@ pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId)
121122
}
122123

123124
/// Returns information about the given implementation.
124-
pub fn get_impl_methods(cstore: &cstore::CStore, impl_def_id: ast::DefId)
125-
-> Vec<ast::DefId> {
125+
pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: ast::DefId)
126+
-> Vec<ty::ImplOrTraitItemId> {
126127
let cdata = cstore.get_crate_data(impl_def_id.krate);
127-
decoder::get_impl_methods(&*cdata, impl_def_id.node)
128+
decoder::get_impl_items(&*cdata, impl_def_id.node)
128129
}
129130

130-
pub fn get_method(tcx: &ty::ctxt, def: ast::DefId) -> ty::Method {
131+
pub fn get_impl_or_trait_item(tcx: &ty::ctxt, def: ast::DefId)
132+
-> ty::ImplOrTraitItem {
131133
let cdata = tcx.sess.cstore.get_crate_data(def.krate);
132-
decoder::get_method(tcx.sess.cstore.intr.clone(), &*cdata, def.node, tcx)
134+
decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(),
135+
&*cdata,
136+
def.node,
137+
tcx)
133138
}
134139

135-
pub fn get_method_name_and_explicit_self(cstore: &cstore::CStore,
136-
def: ast::DefId)
137-
-> (ast::Ident,
138-
ty::ExplicitSelfCategory)
139-
{
140+
pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId)
141+
-> (ast::Ident, resolve::TraitItemKind) {
140142
let cdata = cstore.get_crate_data(def.krate);
141-
decoder::get_method_name_and_explicit_self(cstore.intr.clone(), &*cdata, def.node)
143+
decoder::get_trait_item_name_and_kind(cstore.intr.clone(),
144+
&*cdata,
145+
def.node)
142146
}
143147

144-
pub fn get_trait_method_def_ids(cstore: &cstore::CStore,
145-
def: ast::DefId) -> Vec<ast::DefId> {
148+
pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: ast::DefId)
149+
-> Vec<ty::ImplOrTraitItemId> {
146150
let cdata = cstore.get_crate_data(def.krate);
147-
decoder::get_trait_method_def_ids(&*cdata, def.node)
151+
decoder::get_trait_item_def_ids(&*cdata, def.node)
148152
}
149153

150154
pub fn get_item_variances(cstore: &cstore::CStore,
@@ -286,15 +290,15 @@ pub fn each_implementation_for_trait(cstore: &cstore::CStore,
286290
decoder::each_implementation_for_trait(&*cdata, def_id.node, callback)
287291
}
288292

289-
/// If the given def ID describes a method belonging to a trait (either a
293+
/// If the given def ID describes an item belonging to a trait (either a
290294
/// default method or an implementation of a trait method), returns the ID of
291295
/// the trait that the method belongs to. Otherwise, returns `None`.
292-
pub fn get_trait_of_method(cstore: &cstore::CStore,
293-
def_id: ast::DefId,
294-
tcx: &ty::ctxt)
295-
-> Option<ast::DefId> {
296+
pub fn get_trait_of_item(cstore: &cstore::CStore,
297+
def_id: ast::DefId,
298+
tcx: &ty::ctxt)
299+
-> Option<ast::DefId> {
296300
let cdata = cstore.get_crate_data(def_id.krate);
297-
decoder::get_trait_of_method(&*cdata, def_id.node, tcx)
301+
decoder::get_trait_of_item(&*cdata, def_id.node, tcx)
298302
}
299303

300304
pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,

0 commit comments

Comments
 (0)