Skip to content

Commit

Permalink
Auto merge of #23265 - eddyb:meth-ast-refactor, r=nikomatsakis
Browse files Browse the repository at this point in the history
The end result is that common fields (id, name, attributes, etc.) are stored in now-structures `ImplItem` and `TraitItem`.
The signature of a method is no longer duplicated between methods with a body (default/impl) and those without, they now share `MethodSig`.

This is also a [breaking-change] because of minor bugfixes and changes to syntax extensions:
* `pub fn` methods in a trait no longer parse - remove the `pub`, it has no meaning anymore
* `MacResult::make_methods` is now `make_impl_items` and the return type has changed accordingly
* `quote_method` is gone, because `P<ast::Method>` doesn't exist and it couldn't represent a full method anyways - could be replaced by `quote_impl_item`/`quote_trait_item` in the future, but I do hope we realize how silly that combinatorial macro expansion is and settle on a single `quote` macro + some type hints - or just no types at all (only token-trees)

r? @nikomatsakis This is necessary (hopefully also sufficient) for associated constants.
  • Loading branch information
bors committed Mar 12, 2015
2 parents 538840b + 9da9185 commit c9b03c2
Show file tree
Hide file tree
Showing 59 changed files with 1,516 additions and 2,575 deletions.
41 changes: 16 additions & 25 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,28 +519,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {

fn visit_fn(&mut self, fk: FnKind<'v>, decl: &'v ast::FnDecl,
body: &'v ast::Block, span: Span, id: ast::NodeId) {
match fk {
visit::FkMethod(_, _, m) => {
self.with_lint_attrs(&m.attrs, |cx| {
run_lints!(cx, check_fn, fk, decl, body, span, id);
cx.visit_ids(|v| {
v.visit_fn(fk, decl, body, span, id);
});
visit::walk_fn(cx, fk, decl, body, span);
})
},
_ => {
run_lints!(self, check_fn, fk, decl, body, span, id);
visit::walk_fn(self, fk, decl, body, span);
}
}
}

fn visit_ty_method(&mut self, t: &ast::TypeMethod) {
self.with_lint_attrs(&t.attrs, |cx| {
run_lints!(cx, check_ty_method, t);
visit::walk_ty_method(cx, t);
})
run_lints!(self, check_fn, fk, decl, body, span, id);
visit::walk_fn(self, fk, decl, body, span);
}

fn visit_struct_def(&mut self,
Expand Down Expand Up @@ -611,9 +591,20 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
visit::walk_generics(self, g);
}

fn visit_trait_item(&mut self, m: &ast::TraitItem) {
run_lints!(self, check_trait_item, m);
visit::walk_trait_item(self, m);
fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
self.with_lint_attrs(&trait_item.attrs, |cx| {
run_lints!(cx, check_trait_item, trait_item);
cx.visit_ids(|v| v.visit_trait_item(trait_item));
visit::walk_trait_item(cx, trait_item);
});
}

fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
self.with_lint_attrs(&impl_item.attrs, |cx| {
run_lints!(cx, check_impl_item, impl_item);
cx.visit_ids(|v| v.visit_impl_item(impl_item));
visit::walk_impl_item(cx, impl_item);
});
}

fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option<ast::Lifetime>) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ pub trait LintPass {
fn check_generics(&mut self, _: &Context, _: &ast::Generics) { }
fn check_fn(&mut self, _: &Context,
_: FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { }
fn check_trait_item(&mut self, _: &Context, _: &ast::TraitItem) { }
fn check_impl_item(&mut self, _: &Context, _: &ast::ImplItem) { }
fn check_struct_def(&mut self, _: &Context,
_: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
fn check_struct_def_post(&mut self, _: &Context,
Expand Down
104 changes: 36 additions & 68 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
impl_path: PathElems,
is_default_impl: bool,
parent_id: NodeId,
ast_item_opt: Option<&ast::ImplItem>) {
impl_item_opt: Option<&ast::ImplItem>) {

debug!("encode_info_for_method: {:?} {:?}", m.def_id,
token::get_name(m.name));
Expand All @@ -826,21 +826,20 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,

let elem = ast_map::PathName(m.name);
encode_path(rbml_w, impl_path.chain(Some(elem).into_iter()));
match ast_item_opt {
Some(&ast::MethodImplItem(ref ast_method)) => {
encode_attributes(rbml_w, &ast_method.attrs);
if let Some(impl_item) = impl_item_opt {
if let ast::MethodImplItem(ref sig, _) = impl_item.node {
encode_attributes(rbml_w, &impl_item.attrs);
let scheme = ty::lookup_item_type(ecx.tcx, m.def_id);
let any_types = !scheme.generics.types.is_empty();
if any_types || is_default_impl || attr::requests_inline(&ast_method.attrs) {
if any_types || is_default_impl || attr::requests_inline(&impl_item.attrs) {
encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id),
ast_item_opt.unwrap()));
impl_item));
}
if !any_types {
encode_symbol(ecx, rbml_w, m.def_id.node);
}
encode_method_argument_names(rbml_w, ast_method.pe_fn_decl());
encode_method_argument_names(rbml_w, &sig.decl);
}
Some(_) | None => {}
}

rbml_w.end_tag();
Expand All @@ -851,7 +850,7 @@ fn encode_info_for_associated_type(ecx: &EncodeContext,
associated_type: &ty::AssociatedType,
impl_path: PathElems,
parent_id: NodeId,
typedef_opt: Option<P<ast::Typedef>>) {
impl_item_opt: Option<&ast::ImplItem>) {
debug!("encode_info_for_associated_type({:?},{:?})",
associated_type.def_id,
token::get_name(associated_type.name));
Expand All @@ -873,13 +872,9 @@ fn encode_info_for_associated_type(ecx: &EncodeContext,
let elem = ast_map::PathName(associated_type.name);
encode_path(rbml_w, impl_path.chain(Some(elem).into_iter()));

match typedef_opt {
None => {}
Some(typedef) => {
encode_attributes(rbml_w, &typedef.attrs);
encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx,
typedef.id));
}
if let Some(ii) = impl_item_opt {
encode_attributes(rbml_w, &ii.attrs);
encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx, ii.id));
}

rbml_w.end_tag();
Expand Down Expand Up @@ -1226,7 +1221,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
let num_implemented_methods = ast_items.len();
for (i, &trait_item_def_id) in items.iter().enumerate() {
let ast_item = if i < num_implemented_methods {
Some(&ast_items[i])
Some(&*ast_items[i])
} else {
None
};
Expand All @@ -1236,11 +1231,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
pos: rbml_w.mark_stable_position(),
});

let trait_item_type =
ty::impl_or_trait_item(tcx, trait_item_def_id.def_id());
match (trait_item_type, ast_item) {
(ty::MethodTraitItem(ref method_type),
Some(&ast::MethodImplItem(_))) => {
match ty::impl_or_trait_item(tcx, trait_item_def_id.def_id()) {
ty::MethodTraitItem(ref method_type) => {
encode_info_for_method(ecx,
rbml_w,
&**method_type,
Expand All @@ -1249,31 +1241,13 @@ fn encode_info_for_item(ecx: &EncodeContext,
item.id,
ast_item)
}
(ty::MethodTraitItem(ref method_type), _) => {
encode_info_for_method(ecx,
rbml_w,
&**method_type,
path.clone(),
false,
item.id,
None)
}
(ty::TypeTraitItem(ref associated_type),
Some(&ast::TypeImplItem(ref typedef))) => {
encode_info_for_associated_type(ecx,
rbml_w,
&**associated_type,
path.clone(),
item.id,
Some((*typedef).clone()))
}
(ty::TypeTraitItem(ref associated_type), _) => {
ty::TypeTraitItem(ref associated_type) => {
encode_info_for_associated_type(ecx,
rbml_w,
&**associated_type,
path.clone(),
item.id,
None)
ast_item)
}
}
}
Expand Down Expand Up @@ -1387,35 +1361,29 @@ fn encode_info_for_item(ecx: &EncodeContext,

encode_parent_sort(rbml_w, 't');

let trait_item = &ms[i];
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.
encode_bounds_and_type_for_item(rbml_w, ecx, item_def_id.def_id().local_id());
}
};
match trait_item {
&ast::RequiredMethod(ref m) => {
encode_attributes(rbml_w, &m.attrs);
encode_trait_item(rbml_w);
encode_item_sort(rbml_w, 'r');
encode_method_argument_names(rbml_w, &*m.decl);
}
let trait_item = &*ms[i];
encode_attributes(rbml_w, &trait_item.attrs);
match trait_item.node {
ast::MethodTraitItem(ref sig, ref body) => {
// 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.
encode_bounds_and_type_for_item(rbml_w, ecx,
item_def_id.def_id().local_id());
}

&ast::ProvidedMethod(ref m) => {
encode_attributes(rbml_w, &m.attrs);
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());
if body.is_some() {
encode_item_sort(rbml_w, 'p');
encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item));
} else {
encode_item_sort(rbml_w, 'r');
}
encode_method_argument_names(rbml_w, &sig.decl);
}

&ast::TypeTraitItem(ref associated_type) => {
encode_attributes(rbml_w,
&associated_type.attrs);
ast::TypeTraitItem(..) => {
encode_item_sort(rbml_w, 't');
}
}
Expand Down
63 changes: 13 additions & 50 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin};
use util::ppaux::ty_to_string;

use syntax::{ast, ast_map, ast_util, codemap, fold};
use syntax::ast_util::PostExpansionMethod;
use syntax::codemap::Span;
use syntax::fold::Folder;
use syntax::parse::token;
Expand Down Expand Up @@ -81,11 +80,8 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
let id = match ii {
e::IIItemRef(i) => i.id,
e::IIForeignRef(i) => i.id,
e::IITraitItemRef(_, &ast::ProvidedMethod(ref m)) => m.id,
e::IITraitItemRef(_, &ast::RequiredMethod(ref m)) => m.id,
e::IITraitItemRef(_, &ast::TypeTraitItem(ref ti)) => ti.ty_param.id,
e::IIImplItemRef(_, &ast::MethodImplItem(ref m)) => m.id,
e::IIImplItemRef(_, &ast::TypeImplItem(ref ti)) => ti.id,
e::IITraitItemRef(_, ti) => ti.id,
e::IIImplItemRef(_, ii) => ii.id,
};
debug!("> Encoding inlined item: {} ({:?})",
ecx.tcx.map.path_to_string(id),
Expand Down Expand Up @@ -157,19 +153,8 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
let ident = match *ii {
ast::IIItem(ref i) => i.ident,
ast::IIForeign(ref i) => i.ident,
ast::IITraitItem(_, ref ti) => {
match *ti {
ast::ProvidedMethod(ref m) => m.pe_ident(),
ast::RequiredMethod(ref ty_m) => ty_m.ident,
ast::TypeTraitItem(ref ti) => ti.ty_param.ident,
}
},
ast::IIImplItem(_, ref m) => {
match *m {
ast::MethodImplItem(ref m) => m.pe_ident(),
ast::TypeImplItem(ref ti) => ti.ident,
}
}
ast::IITraitItem(_, ref ti) => ti.ident,
ast::IIImplItem(_, ref ii) => ii.ident
};
debug!("Fn named: {}", token::get_ident(ident));
debug!("< Decoded inlined fn: {}::{}",
Expand Down Expand Up @@ -412,38 +397,16 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
.expect_one("expected one item"))
}
e::IITraitItemRef(d, ti) => {
ast::IITraitItem(d, match *ti {
ast::ProvidedMethod(ref m) => {
ast::ProvidedMethod(
fold::noop_fold_method(m.clone(), &mut fld)
.expect_one("noop_fold_method must produce \
exactly one method"))
}
ast::RequiredMethod(ref ty_m) => {
ast::RequiredMethod(
fold::noop_fold_type_method(ty_m.clone(), &mut fld))
}
ast::TypeTraitItem(ref associated_type) => {
ast::TypeTraitItem(
P(fold::noop_fold_associated_type(
(**associated_type).clone(),
&mut fld)))
}
})
ast::IITraitItem(d,
fold::noop_fold_trait_item(P(ti.clone()), &mut fld)
.expect_one("noop_fold_trait_item must produce \
exactly one trait item"))
}
e::IIImplItemRef(d, m) => {
ast::IIImplItem(d, match *m {
ast::MethodImplItem(ref m) => {
ast::MethodImplItem(
fold::noop_fold_method(m.clone(), &mut fld)
.expect_one("noop_fold_method must produce \
exactly one method"))
}
ast::TypeImplItem(ref td) => {
ast::TypeImplItem(
P(fold::noop_fold_typedef((**td).clone(), &mut fld)))
}
})
e::IIImplItemRef(d, ii) => {
ast::IIImplItem(d,
fold::noop_fold_impl_item(P(ii.clone()), &mut fld)
.expect_one("noop_fold_impl_item must produce \
exactly one impl item"))
}
e::IIForeignRef(i) => {
ast::IIForeign(fold::noop_fold_foreign_item(P(i.clone()), &mut fld))
Expand Down
Loading

0 comments on commit c9b03c2

Please sign in to comment.