mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 08:53:35 +00:00
syntax: gather common fields of impl & trait items into their respective types.
This commit is contained in:
parent
98491827b9
commit
f98b176314
@ -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,
|
||||
@ -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>) {
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
@ -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 ast_method) = 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());
|
||||
}
|
||||
Some(_) | None => {}
|
||||
}
|
||||
|
||||
rbml_w.end_tag();
|
||||
@ -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<&ast::Typedef>) {
|
||||
impl_item_opt: Option<&ast::ImplItem>) {
|
||||
debug!("encode_info_for_associated_type({:?},{:?})",
|
||||
associated_type.def_id,
|
||||
token::get_name(associated_type.name));
|
||||
@ -873,9 +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()));
|
||||
|
||||
if let Some(typedef) = typedef_opt {
|
||||
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();
|
||||
@ -1232,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,
|
||||
@ -1245,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))) => {
|
||||
ty::TypeTraitItem(ref associated_type) => {
|
||||
encode_info_for_associated_type(ecx,
|
||||
rbml_w,
|
||||
&**associated_type,
|
||||
path.clone(),
|
||||
item.id,
|
||||
Some(typedef))
|
||||
}
|
||||
(ty::TypeTraitItem(ref associated_type), _) => {
|
||||
encode_info_for_associated_type(ecx,
|
||||
rbml_w,
|
||||
&**associated_type,
|
||||
path.clone(),
|
||||
item.id,
|
||||
None)
|
||||
ast_item)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1393,25 +1371,22 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||
encode_bounds_and_type_for_item(rbml_w, ecx, item_def_id.def_id().local_id());
|
||||
}
|
||||
};
|
||||
match *trait_item {
|
||||
encode_attributes(rbml_w, &trait_item.attrs);
|
||||
match trait_item.node {
|
||||
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);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
ast::TypeTraitItem(ref associated_type) => {
|
||||
encode_attributes(rbml_w,
|
||||
&associated_type.attrs);
|
||||
ast::TypeTraitItem(..) => {
|
||||
encode_item_sort(rbml_w, 't');
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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),
|
||||
@ -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: {}::{}",
|
||||
@ -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(
|
||||
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(
|
||||
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))
|
||||
|
@ -228,16 +228,11 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
ast_map::NodeTraitItem(trait_method) => {
|
||||
visit::walk_trait_item(self, trait_method);
|
||||
ast_map::NodeTraitItem(trait_item) => {
|
||||
visit::walk_trait_item(self, trait_item);
|
||||
}
|
||||
ast_map::NodeImplItem(impl_item) => {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
visit::walk_method_helper(self, method);
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
}
|
||||
visit::walk_impl_item(self, impl_item);
|
||||
}
|
||||
ast_map::NodeForeignItem(foreign_item) => {
|
||||
visit::walk_foreign_item(self, &*foreign_item);
|
||||
@ -355,11 +350,26 @@ impl<'v> Visitor<'v> for LifeSeeder {
|
||||
ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
|
||||
self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
|
||||
}
|
||||
ast::ItemImpl(_, _, _, Some(ref _trait_ref), _, ref impl_items) => {
|
||||
ast::ItemTrait(_, _, _, ref trait_items) => {
|
||||
for trait_item in trait_items {
|
||||
match trait_item.node {
|
||||
ast::ProvidedMethod(_) => {
|
||||
if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
|
||||
self.worklist.push(trait_item.id);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
self.worklist.push(method.id);
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(_) => {
|
||||
if opt_trait.is_some() ||
|
||||
has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
|
||||
self.worklist.push(impl_item.id);
|
||||
}
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
}
|
||||
@ -369,21 +379,6 @@ impl<'v> Visitor<'v> for LifeSeeder {
|
||||
}
|
||||
visit::walk_item(self, item);
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: visit::FnKind<'v>,
|
||||
_: &'v ast::FnDecl, block: &'v ast::Block,
|
||||
_: codemap::Span, id: ast::NodeId) {
|
||||
// Check for method here because methods are not ast::Item
|
||||
match fk {
|
||||
visit::FkMethod(_, _, method) => {
|
||||
if has_allow_dead_code_or_lang_attr(&method.attrs) {
|
||||
self.worklist.push(id);
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
visit::walk_block(self, block);
|
||||
}
|
||||
}
|
||||
|
||||
fn create_and_seed_worklist(tcx: &ty::ctxt,
|
||||
@ -561,7 +556,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
||||
span: codemap::Span, id: ast::NodeId) {
|
||||
// Have to warn method here because methods are not ast::Item
|
||||
match fk {
|
||||
visit::FkMethod(name, _, _) => {
|
||||
visit::FkMethod(name, _) => {
|
||||
if !self.symbol_is_live(id, None) {
|
||||
self.warn_dead_code(id, span, name, "method");
|
||||
}
|
||||
@ -582,12 +577,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
||||
|
||||
// Overwrite so that we don't warn the trait method itself.
|
||||
fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
|
||||
match *trait_method {
|
||||
match trait_method.node {
|
||||
ast::ProvidedMethod(ref method) => {
|
||||
visit::walk_block(self, &*method.pe_body())
|
||||
visit::walk_block(self, method.pe_body())
|
||||
}
|
||||
ast::RequiredMethod(_) |
|
||||
ast::TypeTraitItem(_) => {}
|
||||
ast::TypeTraitItem(..) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
||||
let (is_item_fn, is_unsafe_fn) = match fn_kind {
|
||||
visit::FkItemFn(_, _, fn_style, _) =>
|
||||
(true, fn_style == ast::Unsafety::Unsafe),
|
||||
visit::FkMethod(_, _, method) =>
|
||||
visit::FkMethod(_, method) =>
|
||||
(true, method.pe_unsafety() == ast::Unsafety::Unsafe),
|
||||
_ => (false, false),
|
||||
};
|
||||
|
@ -846,28 +846,28 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
ast_map::NodeImplItem(ref item) => {
|
||||
match **item {
|
||||
ast_map::NodeImplItem(item) => {
|
||||
match item.node {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
Some((m.pe_fn_decl(),
|
||||
m.pe_generics(),
|
||||
m.pe_unsafety(),
|
||||
m.pe_ident(),
|
||||
item.ident,
|
||||
Some(&m.pe_explicit_self().node),
|
||||
m.span))
|
||||
item.span))
|
||||
}
|
||||
ast::TypeImplItem(_) => None,
|
||||
}
|
||||
},
|
||||
ast_map::NodeTraitItem(ref item) => {
|
||||
match **item {
|
||||
ast_map::NodeTraitItem(item) => {
|
||||
match item.node {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
Some((m.pe_fn_decl(),
|
||||
m.pe_generics(),
|
||||
m.pe_unsafety(),
|
||||
m.pe_ident(),
|
||||
item.ident,
|
||||
Some(&m.pe_explicit_self().node),
|
||||
m.span))
|
||||
item.span))
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
@ -1730,10 +1730,10 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
|
||||
_ => None
|
||||
},
|
||||
ast_map::NodeImplItem(ii) => {
|
||||
match *ii {
|
||||
match ii.node {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
taken.push_all(&m.pe_generics().lifetimes);
|
||||
Some(m.id)
|
||||
Some(ii.id)
|
||||
}
|
||||
ast::TypeImplItem(_) => None,
|
||||
}
|
||||
|
@ -54,8 +54,9 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
|
||||
}
|
||||
|
||||
fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
|
||||
impl_item: &ast::ImplItem,
|
||||
impl_src: ast::DefId) -> bool {
|
||||
if attr::requests_inline(&method.attrs) ||
|
||||
if attr::requests_inline(&impl_item.attrs) ||
|
||||
generics_require_inlining(method.pe_generics()) {
|
||||
return true
|
||||
}
|
||||
@ -66,13 +67,13 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
|
||||
item_might_be_inlined(&*item)
|
||||
}
|
||||
Some(..) | None => {
|
||||
tcx.sess.span_bug(method.span, "impl did is not an item")
|
||||
tcx.sess.span_bug(impl_item.span, "impl did is not an item")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tcx.sess.span_bug(method.span, "found a foreign impl as a parent of a \
|
||||
local method")
|
||||
tcx.sess.span_bug(impl_item.span, "found a foreign impl as a parent \
|
||||
of a local method")
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,17 +182,17 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeTraitItem(trait_method)) => {
|
||||
match *trait_method {
|
||||
match trait_method.node {
|
||||
ast::RequiredMethod(_) => false,
|
||||
ast::ProvidedMethod(_) => true,
|
||||
ast::TypeTraitItem(_) => false,
|
||||
ast::TypeTraitItem(..) => false,
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeImplItem(impl_item)) => {
|
||||
match *impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
if generics_require_inlining(method.pe_generics()) ||
|
||||
attr::requests_inline(&method.attrs) {
|
||||
attr::requests_inline(&impl_item.attrs) {
|
||||
true
|
||||
} else {
|
||||
let impl_did = self.tcx
|
||||
@ -301,21 +302,21 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
ast_map::NodeTraitItem(trait_method) => {
|
||||
match *trait_method {
|
||||
match trait_method.node {
|
||||
ast::RequiredMethod(..) => {
|
||||
// Keep going, nothing to get exported
|
||||
}
|
||||
ast::ProvidedMethod(ref method) => {
|
||||
visit::walk_block(self, &*method.pe_body());
|
||||
}
|
||||
ast::TypeTraitItem(_) => {}
|
||||
ast::TypeTraitItem(..) => {}
|
||||
}
|
||||
}
|
||||
ast_map::NodeImplItem(impl_item) => {
|
||||
match *impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
let did = self.tcx.map.get_parent_did(search_item);
|
||||
if method_might_be_inlined(self.tcx, method, did) {
|
||||
if method_might_be_inlined(self.tcx, method, impl_item, did) {
|
||||
visit::walk_block(self, method.pe_body())
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use middle::subst;
|
||||
use middle::ty;
|
||||
use std::fmt;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::PostExpansionMethod;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::special_idents;
|
||||
use syntax::parse::token;
|
||||
@ -142,12 +143,16 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
|
||||
b: &'v ast::Block, s: Span, _: ast::NodeId) {
|
||||
match fk {
|
||||
visit::FkItemFn(_, generics, _, _) |
|
||||
visit::FkMethod(_, generics, _) => {
|
||||
visit::FkItemFn(_, generics, _, _) => {
|
||||
self.visit_early_late(subst::FnSpace, generics, |this| {
|
||||
visit::walk_fn(this, fk, fd, b, s)
|
||||
})
|
||||
}
|
||||
visit::FkMethod(_, m) => {
|
||||
self.visit_early_late(subst::FnSpace, m.pe_generics(), |this| {
|
||||
visit::walk_fn(this, fk, fd, b, s)
|
||||
})
|
||||
}
|
||||
visit::FkFnBlock(..) => {
|
||||
visit::walk_fn(self, fk, fd, b, s)
|
||||
}
|
||||
@ -185,10 +190,14 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_ty_method(&mut self, m: &ast::TypeMethod) {
|
||||
self.visit_early_late(
|
||||
subst::FnSpace, &m.generics,
|
||||
|this| visit::walk_ty_method(this, m))
|
||||
fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
|
||||
if let ast::RequiredMethod(ref m) = trait_item.node {
|
||||
self.visit_early_late(
|
||||
subst::FnSpace, &m.generics,
|
||||
|this| visit::walk_trait_item(this, trait_item))
|
||||
} else {
|
||||
visit::walk_trait_item(self, trait_item);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b: &ast::Block) {
|
||||
|
@ -22,10 +22,10 @@ use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax::{attr, visit};
|
||||
use syntax::ast;
|
||||
use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
|
||||
use syntax::ast::{Item, TypeMethod, Method, Generics, StructField};
|
||||
use syntax::ast::{Item, Generics, StructField};
|
||||
use syntax::ast_util::is_local;
|
||||
use syntax::attr::{Stability, AttrMetaMethods};
|
||||
use syntax::visit::{FnKind, FkMethod, Visitor};
|
||||
use syntax::visit::{FnKind, Visitor};
|
||||
use syntax::feature_gate::emit_feature_warn;
|
||||
use util::nodemap::{NodeMap, DefIdMap, FnvHashSet, FnvHashMap};
|
||||
use util::ppaux::Repr;
|
||||
@ -123,32 +123,20 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl,
|
||||
_: &'v Block, sp: Span, _: NodeId) {
|
||||
if let FkMethod(_, _, meth) = fk {
|
||||
// Methods are not already annotated, so we annotate it
|
||||
self.annotate(meth.id, true, &meth.attrs, sp, |_| {}, true);
|
||||
}
|
||||
fn visit_fn(&mut self, _: FnKind<'v>, _: &'v FnDecl,
|
||||
_: &'v Block, _: Span, _: NodeId) {
|
||||
// Items defined in a function body have no reason to have
|
||||
// a stability attribute, so we don't recurse.
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, t: &ast::TraitItem) {
|
||||
let (id, attrs, sp) = match *t {
|
||||
ast::RequiredMethod(TypeMethod {id, ref attrs, span, ..}) => (id, attrs, span),
|
||||
fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
|
||||
self.annotate(ti.id, true, &ti.attrs, ti.span,
|
||||
|v| visit::walk_trait_item(v, ti), true);
|
||||
}
|
||||
|
||||
// work around lack of pattern matching for @ types
|
||||
ast::ProvidedMethod(ref method) => {
|
||||
match *method {
|
||||
Method {ref attrs, id, span, ..} => (id, attrs, span),
|
||||
}
|
||||
}
|
||||
|
||||
ast::TypeTraitItem(ref typedef) => {
|
||||
(typedef.ty_param.id, &typedef.attrs, typedef.ty_param.span)
|
||||
}
|
||||
};
|
||||
self.annotate(id, true, attrs, sp, |v| visit::walk_trait_item(v, t), true);
|
||||
fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
|
||||
self.annotate(ii.id, true, &ii.attrs, ii.span,
|
||||
|v| visit::walk_impl_item(v, ii), true);
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
|
||||
@ -335,22 +323,11 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
|
||||
let trait_items = ty::trait_items(tcx, trait_did);
|
||||
|
||||
for impl_item in impl_items {
|
||||
let (ident, span) = match **impl_item {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
(match method.node {
|
||||
ast::MethDecl(ident, _, _, _, _, _, _, _) => ident,
|
||||
ast::MethMac(..) => unreachable!(),
|
||||
}, method.span)
|
||||
}
|
||||
ast::TypeImplItem(ref typedef) => {
|
||||
(typedef.ident, typedef.span)
|
||||
}
|
||||
};
|
||||
let item = trait_items.iter().find(|item| {
|
||||
item.name() == ident.name
|
||||
item.name() == impl_item.ident.name
|
||||
}).unwrap();
|
||||
if warn_about_defns {
|
||||
maybe_do_stability_check(tcx, item.def_id(), span, cb);
|
||||
maybe_do_stability_check(tcx, item.def_id(), impl_item.span, cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2286,7 +2286,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
|
||||
pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
|
||||
match cx.map.find(id) {
|
||||
Some(ast_map::NodeImplItem(ref impl_item)) => {
|
||||
match **impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
let method_def_id = ast_util::local_def(id);
|
||||
match ty::impl_or_trait_item(cx, method_def_id) {
|
||||
@ -2295,7 +2295,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
|
||||
let method_bounds = &method_ty.predicates;
|
||||
construct_parameter_environment(
|
||||
cx,
|
||||
method.span,
|
||||
impl_item.span,
|
||||
method_generics,
|
||||
method_bounds,
|
||||
method.pe_body().id)
|
||||
@ -2315,10 +2315,10 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeTraitItem(trait_method)) => {
|
||||
match *trait_method {
|
||||
ast::RequiredMethod(ref required) => {
|
||||
cx.sess.span_bug(required.span,
|
||||
Some(ast_map::NodeTraitItem(trait_item)) => {
|
||||
match trait_item.node {
|
||||
ast::RequiredMethod(_) => {
|
||||
cx.sess.span_bug(trait_item.span,
|
||||
"ParameterEnvironment::for_item():
|
||||
can't create a parameter \
|
||||
environment for required trait \
|
||||
@ -2332,7 +2332,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
|
||||
let method_bounds = &method_ty.predicates;
|
||||
construct_parameter_environment(
|
||||
cx,
|
||||
method.span,
|
||||
trait_item.span,
|
||||
method_generics,
|
||||
method_bounds,
|
||||
method.pe_body().id)
|
||||
@ -2345,7 +2345,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::TypeTraitItem(_) => {
|
||||
ast::TypeTraitItem(..) => {
|
||||
cx.sess.bug("ParameterEnvironment::from_item(): \
|
||||
can't create a parameter environment \
|
||||
for type trait items")
|
||||
@ -5082,8 +5082,8 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
|
||||
if is_local(id) {
|
||||
if let ItemTrait(_, _, _, ref ms) = cx.map.expect_item(id.node).node {
|
||||
ms.iter().filter_map(|ti| {
|
||||
if let ast::ProvidedMethod(ref m) = **ti {
|
||||
match impl_or_trait_item(cx, ast_util::local_def(m.id)) {
|
||||
if let ast::ProvidedMethod(_) = ti.node {
|
||||
match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
|
||||
MethodTraitItem(m) => Some(m),
|
||||
TypeTraitItem(_) => {
|
||||
cx.sess.bug("provided_trait_methods(): \
|
||||
|
@ -828,14 +828,12 @@ impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> {
|
||||
|
||||
impl<'tcx> Repr<'tcx> for ast::TraitItem {
|
||||
fn repr(&self, _tcx: &ctxt) -> String {
|
||||
match *self {
|
||||
ast::RequiredMethod(ref data) => format!("RequiredMethod({}, id={})",
|
||||
data.ident, data.id),
|
||||
ast::ProvidedMethod(ref data) => format!("ProvidedMethod(id={})",
|
||||
data.id),
|
||||
ast::TypeTraitItem(ref data) => format!("TypeTraitItem({}, id={})",
|
||||
data.ty_param.ident, data.ty_param.id),
|
||||
}
|
||||
let kind = match self.node {
|
||||
ast::RequiredMethod(_) => "RequiredMethod",
|
||||
ast::ProvidedMethod(_) => "ProvidedMethod",
|
||||
ast::TypeTraitItem(..) => "TypeTraitItem",
|
||||
};
|
||||
format!("{}({}, id={})", kind, self.ident, self.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,8 +188,8 @@ mod svh_visitor {
|
||||
SawTy,
|
||||
SawGenerics,
|
||||
SawFn,
|
||||
SawTyMethod,
|
||||
SawTraitMethod,
|
||||
SawTraitItem,
|
||||
SawImplItem,
|
||||
SawStructField,
|
||||
SawVariant,
|
||||
SawExplicitSelf,
|
||||
@ -463,12 +463,12 @@ mod svh_visitor {
|
||||
SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s)
|
||||
}
|
||||
|
||||
fn visit_ty_method(&mut self, t: &TypeMethod) {
|
||||
SawTyMethod.hash(self.st); visit::walk_ty_method(self, t)
|
||||
fn visit_trait_item(&mut self, ti: &TraitItem) {
|
||||
SawTraitItem.hash(self.st); visit::walk_trait_item(self, ti)
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, t: &TraitItem) {
|
||||
SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t)
|
||||
fn visit_impl_item(&mut self, ii: &ImplItem) {
|
||||
SawImplItem.hash(self.st); visit::walk_impl_item(self, ii)
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, s: &StructField) {
|
||||
|
@ -26,7 +26,6 @@ use rustc::util::ppaux::{Repr, UserString};
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
@ -119,24 +118,9 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
sp: Span,
|
||||
id: ast::NodeId) {
|
||||
let (span_err, print) = {
|
||||
let attrs : &[ast::Attribute];
|
||||
attrs = match tcx.map.find(id) {
|
||||
Some(ast_map::NodeItem(ref item)) =>
|
||||
&item.attrs,
|
||||
Some(ast_map::NodeImplItem(&ast::MethodImplItem(ref m))) =>
|
||||
&m.attrs,
|
||||
Some(ast_map::NodeTraitItem(&ast::ProvidedMethod(ref m))) =>
|
||||
&m.attrs,
|
||||
_ => &[],
|
||||
};
|
||||
|
||||
let span_err =
|
||||
attrs.iter().any(|a| a.check_name("rustc_move_fragments"));
|
||||
let print = tcx.sess.opts.debugging_opts.print_move_fragments;
|
||||
|
||||
(span_err, print)
|
||||
};
|
||||
let span_err = tcx.map.attrs(id).iter()
|
||||
.any(|a| a.check_name("rustc_move_fragments"));
|
||||
let print = tcx.sess.opts.debugging_opts.print_move_fragments;
|
||||
|
||||
if !span_err && !print { return; }
|
||||
|
||||
|
@ -46,13 +46,12 @@ use std::{cmp, slice};
|
||||
use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
|
||||
|
||||
use syntax::{abi, ast, ast_map};
|
||||
use syntax::ast_util::is_shift_binop;
|
||||
use syntax::ast_util::{self, is_shift_binop, local_def};
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::codemap::{self, Span};
|
||||
use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
|
||||
use syntax::parse::token;
|
||||
use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
|
||||
use syntax::ast_util;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit::{self, Visitor};
|
||||
|
||||
@ -879,36 +878,18 @@ enum MethodContext {
|
||||
PlainImpl
|
||||
}
|
||||
|
||||
fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
|
||||
let did = ast::DefId {
|
||||
krate: ast::LOCAL_CRATE,
|
||||
node: m.id
|
||||
};
|
||||
|
||||
match cx.tcx.impl_or_trait_items.borrow().get(&did).cloned() {
|
||||
None => cx.sess().span_bug(m.span, "missing method descriptor?!"),
|
||||
Some(ty::MethodTraitItem(md)) => {
|
||||
match md.container {
|
||||
ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
|
||||
ty::ImplContainer(cid) => {
|
||||
match ty::impl_trait_ref(cx.tcx, cid) {
|
||||
Some(..) => MethodContext::TraitImpl,
|
||||
None => MethodContext::PlainImpl
|
||||
}
|
||||
fn method_context(cx: &Context, id: ast::NodeId, span: Span) -> MethodContext {
|
||||
match cx.tcx.impl_or_trait_items.borrow().get(&local_def(id)) {
|
||||
None => cx.sess().span_bug(span, "missing method descriptor?!"),
|
||||
Some(item) => match item.container() {
|
||||
ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
|
||||
ty::ImplContainer(cid) => {
|
||||
match ty::impl_trait_ref(cx.tcx, cid) {
|
||||
Some(_) => MethodContext::TraitImpl,
|
||||
None => MethodContext::PlainImpl
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(ty::TypeTraitItem(typedef)) => {
|
||||
match typedef.container {
|
||||
ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
|
||||
ty::ImplContainer(cid) => {
|
||||
match ty::impl_trait_ref(cx.tcx, cid) {
|
||||
Some(..) => MethodContext::TraitImpl,
|
||||
None => MethodContext::PlainImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -999,9 +980,9 @@ impl LintPass for NonSnakeCase {
|
||||
|
||||
fn check_fn(&mut self, cx: &Context,
|
||||
fk: visit::FnKind, _: &ast::FnDecl,
|
||||
_: &ast::Block, span: Span, _: ast::NodeId) {
|
||||
_: &ast::Block, span: Span, id: ast::NodeId) {
|
||||
match fk {
|
||||
visit::FkMethod(ident, _, m) => match method_context(cx, m) {
|
||||
visit::FkMethod(ident, _) => match method_context(cx, id, span) {
|
||||
MethodContext::PlainImpl => {
|
||||
self.check_snake_case(cx, "method", ident, span)
|
||||
},
|
||||
@ -1023,8 +1004,10 @@ impl LintPass for NonSnakeCase {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_ty_method(&mut self, cx: &Context, t: &ast::TypeMethod) {
|
||||
self.check_snake_case(cx, "trait method", t.ident, t.span);
|
||||
fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
|
||||
if let ast::RequiredMethod(_) = trait_item.node {
|
||||
self.check_snake_case(cx, "trait method", trait_item.ident, trait_item.span);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) {
|
||||
@ -1335,9 +1318,9 @@ impl LintPass for UnsafeCode {
|
||||
visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) =>
|
||||
cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
|
||||
|
||||
visit::FkMethod(_, _, m) => {
|
||||
if let ast::Method_::MethDecl(_, _, _, _, ast::Unsafety::Unsafe, _, _, _) = m.node {
|
||||
cx.span_lint(UNSAFE_CODE, m.span, "implementation of an `unsafe` method")
|
||||
visit::FkMethod(_, m) => {
|
||||
if let ast::MethDecl(_, _, _, ast::Unsafety::Unsafe, _, _) = *m {
|
||||
cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method")
|
||||
}
|
||||
},
|
||||
|
||||
@ -1345,9 +1328,12 @@ impl LintPass for UnsafeCode {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_ty_method(&mut self, cx: &Context, ty_method: &ast::TypeMethod) {
|
||||
if let ast::TypeMethod { unsafety: ast::Unsafety::Unsafe, span, ..} = *ty_method {
|
||||
cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method")
|
||||
fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
|
||||
if let ast::RequiredMethod(ref m) = trait_item.node {
|
||||
if m.unsafety == ast::Unsafety::Unsafe {
|
||||
cx.span_lint(UNSAFE_CODE, trait_item.span,
|
||||
"declaration of an `unsafe` method")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1576,30 +1562,30 @@ impl LintPass for MissingDoc {
|
||||
self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
|
||||
}
|
||||
|
||||
fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
|
||||
_: &ast::Block, _: Span, _: ast::NodeId) {
|
||||
if let visit::FkMethod(_, _, m) = fk {
|
||||
// If the method is an impl for a trait, don't doc.
|
||||
if method_context(cx, m) == MethodContext::TraitImpl {
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, doc according to privacy. This will also check
|
||||
// doc for default methods defined on traits.
|
||||
self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs, m.span, "a method");
|
||||
}
|
||||
fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
|
||||
let desc = match trait_item.node {
|
||||
ast::ProvidedMethod(_) => "a default method",
|
||||
ast::RequiredMethod(_) => "a trait method",
|
||||
ast::TypeTraitItem(..) => "an associated type"
|
||||
};
|
||||
self.check_missing_docs_attrs(cx, Some(trait_item.id),
|
||||
&trait_item.attrs,
|
||||
trait_item.span, desc);
|
||||
}
|
||||
|
||||
fn check_ty_method(&mut self, cx: &Context, tm: &ast::TypeMethod) {
|
||||
self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs, tm.span, "a type method");
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &Context, it: &ast::TraitItem) {
|
||||
if let ast::TraitItem::TypeTraitItem(ref ty) = *it {
|
||||
let assoc_ty = &ty.ty_param;
|
||||
self.check_missing_docs_attrs(cx, Some(assoc_ty.id), &ty.attrs,
|
||||
assoc_ty.span, "an associated type");
|
||||
fn check_impl_item(&mut self, cx: &Context, impl_item: &ast::ImplItem) {
|
||||
// If the method is an impl for a trait, don't doc.
|
||||
if method_context(cx, impl_item.id, impl_item.span) == MethodContext::TraitImpl {
|
||||
return;
|
||||
}
|
||||
|
||||
let desc = match impl_item.node {
|
||||
ast::MethodImplItem(_) => "a method",
|
||||
ast::TypeImplItem(_) => "an associated type"
|
||||
};
|
||||
self.check_missing_docs_attrs(cx, Some(impl_item.id),
|
||||
&impl_item.attrs,
|
||||
impl_item.span, desc);
|
||||
}
|
||||
|
||||
fn check_struct_field(&mut self, cx: &Context, sf: &ast::StructField) {
|
||||
@ -1644,10 +1630,7 @@ impl LintPass for MissingCopyImplementations {
|
||||
if !cx.exported_items.contains(&item.id) {
|
||||
return;
|
||||
}
|
||||
if cx.tcx
|
||||
.destructor_for_type
|
||||
.borrow()
|
||||
.contains_key(&ast_util::local_def(item.id)) {
|
||||
if cx.tcx.destructor_for_type.borrow().contains_key(&local_def(item.id)) {
|
||||
return;
|
||||
}
|
||||
let ty = match item.node {
|
||||
@ -1655,16 +1638,14 @@ impl LintPass for MissingCopyImplementations {
|
||||
if ast_generics.is_parameterized() {
|
||||
return;
|
||||
}
|
||||
ty::mk_struct(cx.tcx,
|
||||
ast_util::local_def(item.id),
|
||||
ty::mk_struct(cx.tcx, local_def(item.id),
|
||||
cx.tcx.mk_substs(Substs::empty()))
|
||||
}
|
||||
ast::ItemEnum(_, ref ast_generics) => {
|
||||
if ast_generics.is_parameterized() {
|
||||
return;
|
||||
}
|
||||
ty::mk_enum(cx.tcx,
|
||||
ast_util::local_def(item.id),
|
||||
ty::mk_enum(cx.tcx, local_def(item.id),
|
||||
cx.tcx.mk_substs(Substs::empty()))
|
||||
}
|
||||
_ => return,
|
||||
@ -1828,13 +1809,13 @@ impl LintPass for UnconditionalRecursion {
|
||||
|
||||
let (name, checker) = match fn_kind {
|
||||
visit::FkItemFn(name, _, _, _) => (name, id_refers_to_this_fn as F),
|
||||
visit::FkMethod(name, _, _) => (name, id_refers_to_this_method as F),
|
||||
visit::FkMethod(name, _) => (name, id_refers_to_this_method as F),
|
||||
// closures can't recur, so they don't matter.
|
||||
visit::FkFnBlock => return
|
||||
};
|
||||
|
||||
let impl_def_id = ty::impl_of_method(cx.tcx, ast_util::local_def(id))
|
||||
.unwrap_or(ast_util::local_def(ast::DUMMY_NODE_ID));
|
||||
let impl_def_id = ty::impl_of_method(cx.tcx, local_def(id))
|
||||
.unwrap_or(local_def(ast::DUMMY_NODE_ID));
|
||||
assert!(ast_util::is_local(impl_def_id));
|
||||
let impl_node_id = impl_def_id.node;
|
||||
|
||||
@ -1938,7 +1919,7 @@ impl LintPass for UnconditionalRecursion {
|
||||
_: ast::Ident,
|
||||
id: ast::NodeId) -> bool {
|
||||
tcx.def_map.borrow().get(&id)
|
||||
.map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
|
||||
.map_or(false, |def| def.def_id() == local_def(fn_id))
|
||||
}
|
||||
|
||||
// check if the method call `id` refers to method `method_id`
|
||||
|
@ -92,17 +92,9 @@ impl<'v> Visitor<'v> for ParentVisitor {
|
||||
// method to the root. In this case, if the trait is private, then
|
||||
// parent all the methods to the trait to indicate that they're
|
||||
// private.
|
||||
ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => {
|
||||
for m in methods {
|
||||
match **m {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
self.parents.insert(m.id, item.id);
|
||||
}
|
||||
ast::RequiredMethod(ref m) => {
|
||||
self.parents.insert(m.id, item.id);
|
||||
}
|
||||
ast::TypeTraitItem(_) => {}
|
||||
};
|
||||
ast::ItemTrait(_, _, _, ref trait_items) if item.vis != ast::Public => {
|
||||
for trait_item in trait_items {
|
||||
self.parents.insert(trait_item.id, item.id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,15 +272,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||
|
||||
if public_ty || public_trait {
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
let meth_public =
|
||||
match method.pe_explicit_self().node {
|
||||
ast::SelfStatic => public_ty,
|
||||
_ => true,
|
||||
} && method.pe_vis() == ast::Public;
|
||||
} && impl_item.vis == ast::Public;
|
||||
if meth_public || tr.is_some() {
|
||||
self.exported_items.insert(method.id);
|
||||
self.exported_items.insert(impl_item.id);
|
||||
}
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
@ -299,22 +291,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||
|
||||
// Default methods on traits are all public so long as the trait
|
||||
// is public
|
||||
ast::ItemTrait(_, _, _, ref methods) if public_first => {
|
||||
for method in methods {
|
||||
match **method {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
debug!("provided {}", m.id);
|
||||
self.exported_items.insert(m.id);
|
||||
}
|
||||
ast::RequiredMethod(ref m) => {
|
||||
debug!("required {}", m.id);
|
||||
self.exported_items.insert(m.id);
|
||||
}
|
||||
ast::TypeTraitItem(ref t) => {
|
||||
debug!("typedef {}", t.ty_param.id);
|
||||
self.exported_items.insert(t.ty_param.id);
|
||||
}
|
||||
}
|
||||
ast::ItemTrait(_, _, _, ref trait_items) if public_first => {
|
||||
for trait_item in trait_items {
|
||||
debug!("trait item {}", trait_item.id);
|
||||
self.exported_items.insert(trait_item.id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -510,16 +490,16 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||
// FIXME(#10573) is this the right behavior? Why not consider
|
||||
// where the method was defined?
|
||||
Some(ast_map::NodeImplItem(ii)) => {
|
||||
match *ii {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
match ii.node {
|
||||
ast::MethodImplItem(_) => {
|
||||
let imp = self.tcx.map
|
||||
.get_parent_did(closest_private_id);
|
||||
match ty::impl_trait_ref(self.tcx, imp) {
|
||||
Some(..) => return Allowable,
|
||||
_ if m.pe_vis() == ast::Public => {
|
||||
_ if ii.vis == ast::Public => {
|
||||
return Allowable
|
||||
}
|
||||
_ => m.pe_vis()
|
||||
_ => ii.vis
|
||||
}
|
||||
}
|
||||
ast::TypeImplItem(_) => return Allowable,
|
||||
@ -1088,12 +1068,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||
"visibility qualifiers have no effect on trait \
|
||||
impls");
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
check_inherited(m.span, m.pe_vis(), "");
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
}
|
||||
check_inherited(impl_item.span, impl_item.vis, "");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1121,23 +1096,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemTrait(_, _, _, ref methods) => {
|
||||
for m in methods {
|
||||
match **m {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
check_inherited(m.span, m.pe_vis(),
|
||||
"unnecessary visibility");
|
||||
}
|
||||
ast::RequiredMethod(ref m) => {
|
||||
check_inherited(m.span, m.vis,
|
||||
"unnecessary visibility");
|
||||
}
|
||||
ast::TypeTraitItem(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemDefaultImpl(..) |
|
||||
ast::ItemTrait(..) | ast::ItemDefaultImpl(..) |
|
||||
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
|
||||
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
|
||||
ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemMac(..) => {}
|
||||
@ -1165,9 +1124,9 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||
match item.node {
|
||||
ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
check_inherited(tcx, m.span, m.pe_vis());
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(_) => {
|
||||
check_inherited(tcx, impl_item.span, impl_item.vis);
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
}
|
||||
@ -1186,18 +1145,8 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||
|
||||
ast::ItemStruct(ref def, _) => check_struct(&**def),
|
||||
|
||||
ast::ItemTrait(_, _, _, ref methods) => {
|
||||
for m in methods {
|
||||
match **m {
|
||||
ast::RequiredMethod(..) => {}
|
||||
ast::ProvidedMethod(ref m) => check_inherited(tcx, m.span,
|
||||
m.pe_vis()),
|
||||
ast::TypeTraitItem(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemDefaultImpl(..) | ast::ItemExternCrate(_) | ast::ItemUse(_) |
|
||||
ast::ItemExternCrate(_) | ast::ItemUse(_) |
|
||||
ast::ItemTrait(..) | ast::ItemDefaultImpl(..) |
|
||||
ast::ItemStatic(..) | ast::ItemConst(..) |
|
||||
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
|
||||
ast::ItemMac(..) => {}
|
||||
@ -1352,9 +1301,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
trait_ref.is_some() ||
|
||||
impl_items.iter()
|
||||
.any(|impl_item| {
|
||||
match **impl_item {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
self.exported_items.contains(&m.id)
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(_) => {
|
||||
self.exported_items.contains(&impl_item.id)
|
||||
}
|
||||
ast::TypeImplItem(_) => false,
|
||||
}
|
||||
@ -1369,12 +1318,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
match *trait_ref {
|
||||
None => {
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
visit::walk_method_helper(self, method)
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
}
|
||||
visit::walk_impl_item(self, impl_item);
|
||||
}
|
||||
}
|
||||
Some(ref tr) => {
|
||||
@ -1395,10 +1339,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
|
||||
// Those in 3. are warned with this call.
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(..) => {},
|
||||
ast::TypeImplItem(ref typedef) => {
|
||||
self.visit_ty(&typedef.typ);
|
||||
ast::TypeImplItem(ref ty) => {
|
||||
self.visit_ty(ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1409,14 +1353,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
// methods will be visible as `Public::foo`.
|
||||
let mut found_pub_static = false;
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
if method.pe_explicit_self().node ==
|
||||
ast::SelfStatic &&
|
||||
self.exported_items
|
||||
.contains(&method.id) {
|
||||
.contains(&impl_item.id) {
|
||||
found_pub_static = true;
|
||||
visit::walk_method_helper(self, method);
|
||||
visit::walk_impl_item(self, impl_item);
|
||||
}
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
|
@ -48,7 +48,7 @@ use syntax::ast::UnnamedField;
|
||||
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use syntax::ast::{Visibility};
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::{self, local_def, PostExpansionMethod};
|
||||
use syntax::ast_util::local_def;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::parse::token::{self, special_idents};
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
@ -525,53 +525,29 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||
|
||||
// Add the names of all the items to the trait info.
|
||||
for trait_item in items {
|
||||
let (name, trait_item_id) = match **trait_item {
|
||||
let name_bindings = self.add_child(trait_item.ident.name,
|
||||
&module_parent,
|
||||
ForbidDuplicateTypesAndValues,
|
||||
trait_item.span);
|
||||
|
||||
match trait_item.node {
|
||||
ast::RequiredMethod(_) |
|
||||
ast::ProvidedMethod(_) => {
|
||||
let (id, name, span) = match **trait_item {
|
||||
ast::RequiredMethod(ref m) => {
|
||||
(m.id, m.ident.name, m.span)
|
||||
}
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
(m.id, m.pe_ident().name, m.span)
|
||||
}
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
// Add it as a name in the trait module.
|
||||
let def = DefMethod(local_def(id),
|
||||
let def = DefMethod(local_def(trait_item.id),
|
||||
FromTrait(local_def(item.id)));
|
||||
|
||||
let method_name_bindings =
|
||||
self.add_child(name,
|
||||
&module_parent,
|
||||
ForbidDuplicateTypesAndValues,
|
||||
span);
|
||||
// NB: not IMPORTABLE
|
||||
method_name_bindings.define_value(def, span, PUBLIC);
|
||||
|
||||
(name, local_def(id))
|
||||
name_bindings.define_value(def, trait_item.span, PUBLIC);
|
||||
}
|
||||
ast::TypeTraitItem(ref associated_type) => {
|
||||
ast::TypeTraitItem(..) => {
|
||||
let def = DefAssociatedTy(local_def(item.id),
|
||||
local_def(associated_type.ty_param.id));
|
||||
|
||||
let name_bindings =
|
||||
self.add_child(associated_type.ty_param.ident.name,
|
||||
&module_parent,
|
||||
ForbidDuplicateTypesAndValues,
|
||||
associated_type.ty_param.span);
|
||||
local_def(trait_item.id));
|
||||
// NB: not IMPORTABLE
|
||||
name_bindings.define_type(def,
|
||||
associated_type.ty_param.span,
|
||||
PUBLIC);
|
||||
|
||||
(associated_type.ty_param.ident.name,
|
||||
local_def(associated_type.ty_param.id))
|
||||
name_bindings.define_type(def, trait_item.span, PUBLIC);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
self.trait_item_map.insert((name, def_id), trait_item_id);
|
||||
self.trait_item_map.insert((trait_item.ident.name, def_id),
|
||||
local_def(trait_item.id));
|
||||
}
|
||||
|
||||
name_bindings.define_type(DefTrait(def_id), sp, modifiers);
|
||||
|
@ -242,8 +242,8 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
|
||||
self.visit_generics(generics);
|
||||
ItemRibKind
|
||||
}
|
||||
visit::FkMethod(_, generics, method) => {
|
||||
self.visit_generics(generics);
|
||||
visit::FkMethod(_, method) => {
|
||||
self.visit_generics(method.pe_generics());
|
||||
self.visit_explicit_self(method.pe_explicit_self());
|
||||
MethodRibKind
|
||||
}
|
||||
@ -2807,13 +2807,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
this.visit_generics(generics);
|
||||
visit::walk_ty_param_bounds_helper(this, bounds);
|
||||
|
||||
for trait_item in &(*trait_items) {
|
||||
for trait_item in trait_items {
|
||||
// Create a new rib for the trait_item-specific type
|
||||
// parameters.
|
||||
//
|
||||
// FIXME #4951: Do we need a node ID here?
|
||||
|
||||
let type_parameters = match **trait_item {
|
||||
let type_parameters = match trait_item.node {
|
||||
ast::RequiredMethod(ref ty_m) => {
|
||||
HasTypeParameters(&ty_m.generics,
|
||||
FnSpace,
|
||||
@ -2824,10 +2824,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
FnSpace,
|
||||
MethodRibKind)
|
||||
}
|
||||
ast::TypeTraitItem(ref assoc_ty) => {
|
||||
let ty_param = &assoc_ty.ty_param;
|
||||
this.check_if_primitive_type_name(ty_param.ident.name,
|
||||
ty_param.span);
|
||||
ast::TypeTraitItem(..) => {
|
||||
this.check_if_primitive_type_name(trait_item.ident.name,
|
||||
trait_item.span);
|
||||
NoTypeParameters
|
||||
}
|
||||
};
|
||||
@ -3066,12 +3065,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
this.with_current_self_type(self_type, |this| {
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
match impl_item.node {
|
||||
MethodImplItem(ref method) => {
|
||||
// If this is a trait impl, ensure the method
|
||||
// exists in trait
|
||||
this.check_trait_item(method.pe_ident().name,
|
||||
method.span);
|
||||
this.check_trait_item(impl_item.ident.name,
|
||||
impl_item.span);
|
||||
|
||||
// We also need a new scope for the method-
|
||||
// specific type parameters.
|
||||
@ -3080,16 +3079,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
FnSpace,
|
||||
MethodRibKind);
|
||||
this.with_type_parameter_rib(type_parameters, |this| {
|
||||
visit::walk_method_helper(this, method);
|
||||
visit::walk_impl_item(this, impl_item);
|
||||
});
|
||||
}
|
||||
TypeImplItem(ref typedef) => {
|
||||
TypeImplItem(ref ty) => {
|
||||
// If this is a trait impl, ensure the method
|
||||
// exists in trait
|
||||
this.check_trait_item(typedef.ident.name,
|
||||
typedef.span);
|
||||
this.check_trait_item(impl_item.ident.name,
|
||||
impl_item.span);
|
||||
|
||||
this.visit_ty(&*typedef.typ);
|
||||
this.visit_ty(ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3955,12 +3954,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
fn is_static_method(this: &Resolver, did: DefId) -> bool {
|
||||
if did.krate == ast::LOCAL_CRATE {
|
||||
let explicit_self = match this.ast_map.get(did.node) {
|
||||
ast_map::NodeTraitItem(m) => match *m {
|
||||
ast_map::NodeTraitItem(trait_item) => match trait_item.node {
|
||||
ast::RequiredMethod(ref m) => &m.explicit_self,
|
||||
ast::ProvidedMethod(ref m) => m.pe_explicit_self(),
|
||||
_ => return false
|
||||
},
|
||||
ast_map::NodeImplItem(m) => match *m {
|
||||
ast_map::NodeImplItem(impl_item) => match impl_item.node {
|
||||
ast::MethodImplItem(ref m) => m.pe_explicit_self(),
|
||||
_ => return false
|
||||
},
|
||||
|
@ -284,8 +284,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn process_method(&mut self, method: &ast::Method) {
|
||||
if generated_code(method.span) {
|
||||
fn process_method(&mut self, method: &ast::Method,
|
||||
id: ast::NodeId, ident: ast::Ident,
|
||||
span: Span) {
|
||||
if generated_code(span) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -293,7 +295,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
// The qualname for a method is the trait name or name of the struct in an impl in
|
||||
// which the method is declared in, followed by the method's name.
|
||||
let qualname = match ty::impl_of_method(&self.analysis.ty_cx,
|
||||
ast_util::local_def(method.id)) {
|
||||
ast_util::local_def(id)) {
|
||||
Some(impl_id) => match self.analysis.ty_cx.map.get(impl_id.node) {
|
||||
NodeItem(item) => {
|
||||
scope_id = item.id;
|
||||
@ -303,7 +305,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
result.push_str(&ty_to_string(&**ty));
|
||||
|
||||
match ty::trait_of_item(&self.analysis.ty_cx,
|
||||
ast_util::local_def(method.id)) {
|
||||
ast_util::local_def(id)) {
|
||||
Some(def_id) => {
|
||||
result.push_str(" as ");
|
||||
result.push_str(
|
||||
@ -315,23 +317,20 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
result
|
||||
}
|
||||
_ => {
|
||||
self.sess.span_bug(method.span,
|
||||
&format!("Container {} for method {} not an impl?",
|
||||
impl_id.node, method.id));
|
||||
self.sess.span_bug(span,
|
||||
&format!("Container {} for method {} not an impl?",
|
||||
impl_id.node, id));
|
||||
},
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
self.sess.span_bug(method.span,
|
||||
&format!(
|
||||
"Container {} for method {} is not a node item {:?}",
|
||||
impl_id.node,
|
||||
method.id,
|
||||
self.analysis.ty_cx.map.get(impl_id.node)));
|
||||
self.sess.span_bug(span,
|
||||
&format!("Container {} for method {} is not a node item {:?}",
|
||||
impl_id.node, id, self.analysis.ty_cx.map.get(impl_id.node)));
|
||||
},
|
||||
},
|
||||
None => match ty::trait_of_item(&self.analysis.ty_cx,
|
||||
ast_util::local_def(method.id)) {
|
||||
ast_util::local_def(id)) {
|
||||
Some(def_id) => {
|
||||
scope_id = def_id.node;
|
||||
match self.analysis.ty_cx.map.get(def_id.node) {
|
||||
@ -339,30 +338,29 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
format!("::{}", ty::item_path_str(&self.analysis.ty_cx, def_id))
|
||||
}
|
||||
_ => {
|
||||
self.sess.span_bug(method.span,
|
||||
&format!("Could not find container {} for method {}",
|
||||
def_id.node, method.id));
|
||||
self.sess.span_bug(span,
|
||||
&format!("Could not find container {} for method {}",
|
||||
def_id.node, id));
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
self.sess.span_bug(method.span,
|
||||
&format!("Could not find container for method {}",
|
||||
method.id));
|
||||
self.sess.span_bug(span,
|
||||
&format!("Could not find container for method {}", id));
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let qualname = format!("{}::{}", qualname, &get_ident(method.pe_ident()));
|
||||
let qualname = format!("{}::{}", qualname, &get_ident(ident));
|
||||
let qualname = &qualname[..];
|
||||
|
||||
// record the decl for this def (if it has one)
|
||||
let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx,
|
||||
ast_util::local_def(method.id))
|
||||
ast_util::local_def(id))
|
||||
.and_then(|def_id| {
|
||||
if match def_id {
|
||||
ty::MethodTraitItemId(def_id) => {
|
||||
def_id.node != 0 && def_id != ast_util::local_def(method.id)
|
||||
def_id.node != 0 && def_id != ast_util::local_def(id)
|
||||
}
|
||||
ty::TypeTraitItemId(_) => false,
|
||||
} {
|
||||
@ -376,10 +374,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
Some(id) => Some(id.def_id()),
|
||||
};
|
||||
|
||||
let sub_span = self.span.sub_span_after_keyword(method.span, keywords::Fn);
|
||||
self.fmt.method_str(method.span,
|
||||
let sub_span = self.span.sub_span_after_keyword(span, keywords::Fn);
|
||||
self.fmt.method_str(span,
|
||||
sub_span,
|
||||
method.id,
|
||||
id,
|
||||
qualname,
|
||||
decl_id,
|
||||
scope_id);
|
||||
@ -396,12 +394,12 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
}
|
||||
|
||||
// walk the fn body
|
||||
self.nest(method.id, |v| v.visit_block(&*method.pe_body()));
|
||||
self.nest(id, |v| v.visit_block(&*method.pe_body()));
|
||||
|
||||
self.process_generic_params(method.pe_generics(),
|
||||
method.span,
|
||||
span,
|
||||
qualname,
|
||||
method.id);
|
||||
id);
|
||||
}
|
||||
|
||||
fn process_trait_ref(&mut self,
|
||||
@ -698,14 +696,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
|
||||
self.process_generic_params(type_parameters, item.span, "", item.id);
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
visit::walk_method_helper(self, method)
|
||||
}
|
||||
ast::TypeImplItem(ref typedef) => {
|
||||
visit::walk_ty(self, &*typedef.typ)
|
||||
}
|
||||
}
|
||||
visit::walk_impl_item(self, impl_item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1233,52 +1224,34 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// We don't actually index functions here, that is done in visit_item/ItemFn.
|
||||
// Here we just visit methods.
|
||||
fn visit_fn(&mut self,
|
||||
fk: visit::FnKind<'v>,
|
||||
fd: &'v ast::FnDecl,
|
||||
b: &'v ast::Block,
|
||||
s: Span,
|
||||
_: ast::NodeId) {
|
||||
if generated_code(s) {
|
||||
return;
|
||||
}
|
||||
|
||||
match fk {
|
||||
visit::FkMethod(_, _, method) => self.process_method(method),
|
||||
_ => visit::walk_fn(self, fk, fd, b, s),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
|
||||
match *tm {
|
||||
fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
|
||||
match trait_item.node {
|
||||
ast::RequiredMethod(ref method_type) => {
|
||||
if generated_code(method_type.span) {
|
||||
if generated_code(trait_item.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut scope_id;
|
||||
let mut qualname = match ty::trait_of_item(&self.analysis.ty_cx,
|
||||
ast_util::local_def(method_type.id)) {
|
||||
ast_util::local_def(trait_item.id)) {
|
||||
Some(def_id) => {
|
||||
scope_id = def_id.node;
|
||||
format!("::{}::", ty::item_path_str(&self.analysis.ty_cx, def_id))
|
||||
},
|
||||
None => {
|
||||
self.sess.span_bug(method_type.span,
|
||||
self.sess.span_bug(trait_item.span,
|
||||
&format!("Could not find trait for method {}",
|
||||
method_type.id));
|
||||
trait_item.id));
|
||||
},
|
||||
};
|
||||
|
||||
qualname.push_str(&get_ident(method_type.ident));
|
||||
qualname.push_str(&get_ident(trait_item.ident));
|
||||
let qualname = &qualname[..];
|
||||
|
||||
let sub_span = self.span.sub_span_after_keyword(method_type.span, keywords::Fn);
|
||||
self.fmt.method_decl_str(method_type.span,
|
||||
let sub_span = self.span.sub_span_after_keyword(trait_item.span, keywords::Fn);
|
||||
self.fmt.method_decl_str(trait_item.span,
|
||||
sub_span,
|
||||
method_type.id,
|
||||
trait_item.id,
|
||||
qualname,
|
||||
scope_id);
|
||||
|
||||
@ -1292,12 +1265,23 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
||||
}
|
||||
|
||||
self.process_generic_params(&method_type.generics,
|
||||
method_type.span,
|
||||
trait_item.span,
|
||||
qualname,
|
||||
method_type.id);
|
||||
trait_item.id);
|
||||
}
|
||||
ast::ProvidedMethod(ref method) => self.process_method(method),
|
||||
ast::TypeTraitItem(_) => {}
|
||||
ast::ProvidedMethod(ref method) => {
|
||||
self.process_method(method, trait_item.id, trait_item.ident, trait_item.span);
|
||||
}
|
||||
ast::TypeTraitItem(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
self.process_method(method, impl_item.id, impl_item.ident, impl_item.span);
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ use std::rc::Rc;
|
||||
use std::str;
|
||||
use std::{i8, i16, i32, i64};
|
||||
use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi};
|
||||
use syntax::ast_util::local_def;
|
||||
use syntax::ast_util::{local_def, PostExpansionMethod};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
@ -1263,41 +1263,27 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
|
||||
Some(ast_map::NodeItem(i)) => {
|
||||
match i.node {
|
||||
ast::ItemFn(_, _, _, _, ref blk) => {
|
||||
blk
|
||||
&**blk
|
||||
}
|
||||
_ => tcx.sess.bug("unexpected item variant in has_nested_returns")
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeTraitItem(trait_method)) => {
|
||||
match *trait_method {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
match m.node {
|
||||
ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
|
||||
blk
|
||||
}
|
||||
ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeTraitItem(trait_item)) => {
|
||||
match trait_item.node {
|
||||
ast::ProvidedMethod(ref m) => m.pe_body(),
|
||||
ast::RequiredMethod(_) => {
|
||||
tcx.sess.bug("unexpected variant: required trait method \
|
||||
in has_nested_returns")
|
||||
}
|
||||
ast::TypeTraitItem(_) => {
|
||||
ast::TypeTraitItem(..) => {
|
||||
tcx.sess.bug("unexpected variant: associated type trait item in \
|
||||
has_nested_returns")
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeImplItem(ii)) => {
|
||||
match *ii {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
match m.node {
|
||||
ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
|
||||
blk
|
||||
}
|
||||
ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeImplItem(impl_item)) => {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref m) => m.pe_body(),
|
||||
ast::TypeImplItem(_) => {
|
||||
tcx.sess.bug("unexpected variant: associated type impl item in \
|
||||
has_nested_returns")
|
||||
@ -1306,9 +1292,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
|
||||
}
|
||||
Some(ast_map::NodeExpr(e)) => {
|
||||
match e.node {
|
||||
ast::ExprClosure(_, _, ref blk) => {
|
||||
blk
|
||||
}
|
||||
ast::ExprClosure(_, _, ref blk) => &**blk,
|
||||
_ => tcx.sess.bug("unexpected expr variant in has_nested_returns")
|
||||
}
|
||||
}
|
||||
@ -1322,7 +1306,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
|
||||
tcx.map.path_to_string(id)))
|
||||
};
|
||||
|
||||
(blk.id, Some(cfg::CFG::new(tcx, &**blk)))
|
||||
(blk.id, Some(cfg::CFG::new(tcx, blk)))
|
||||
}
|
||||
|
||||
// Checks for the presence of "nested returns" in a function.
|
||||
@ -2818,26 +2802,27 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
||||
v
|
||||
}
|
||||
|
||||
ast_map::NodeTraitItem(trait_method) => {
|
||||
ast_map::NodeTraitItem(trait_item) => {
|
||||
debug!("get_item_val(): processing a NodeTraitItem");
|
||||
match *trait_method {
|
||||
ast::RequiredMethod(_) | ast::TypeTraitItem(_) => {
|
||||
ccx.sess().bug("unexpected variant: required trait \
|
||||
method in get_item_val()");
|
||||
match trait_item.node {
|
||||
ast::RequiredMethod(_) | ast::TypeTraitItem(..) => {
|
||||
ccx.sess().span_bug(trait_item.span,
|
||||
"unexpected variant: required trait method in get_item_val()");
|
||||
}
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
register_method(ccx, id, m)
|
||||
ast::ProvidedMethod(_) => {
|
||||
register_method(ccx, id, &trait_item.attrs, trait_item.span)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast_map::NodeImplItem(ii) => {
|
||||
match *ii {
|
||||
ast::MethodImplItem(ref m) => register_method(ccx, id, m),
|
||||
ast::TypeImplItem(ref typedef) => {
|
||||
ccx.sess().span_bug(typedef.span,
|
||||
"unexpected variant: associated type \
|
||||
in get_item_val()")
|
||||
ast_map::NodeImplItem(impl_item) => {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(_) => {
|
||||
register_method(ccx, id, &impl_item.attrs, impl_item.span)
|
||||
}
|
||||
ast::TypeImplItem(_) => {
|
||||
ccx.sess().span_bug(impl_item.span,
|
||||
"unexpected variant: associated type in get_item_val()")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2925,21 +2910,21 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
||||
}
|
||||
|
||||
fn register_method(ccx: &CrateContext, id: ast::NodeId,
|
||||
m: &ast::Method) -> ValueRef {
|
||||
attrs: &[ast::Attribute], span: Span) -> ValueRef {
|
||||
let mty = ty::node_id_to_type(ccx.tcx(), id);
|
||||
|
||||
let sym = exported_name(ccx, id, mty, &m.attrs);
|
||||
let sym = exported_name(ccx, id, mty, &attrs);
|
||||
|
||||
if let ty::ty_bare_fn(_, ref f) = mty.sty {
|
||||
let llfn = if f.abi == Rust || f.abi == RustCall {
|
||||
register_fn(ccx, m.span, sym, id, mty)
|
||||
register_fn(ccx, span, sym, id, mty)
|
||||
} else {
|
||||
foreign::register_rust_fn_with_foreign_abi(ccx, m.span, sym, id)
|
||||
foreign::register_rust_fn_with_foreign_abi(ccx, span, sym, id)
|
||||
};
|
||||
set_llvm_fn_attrs(ccx, &m.attrs, llfn);
|
||||
set_llvm_fn_attrs(ccx, &attrs, llfn);
|
||||
return llfn;
|
||||
} else {
|
||||
ccx.sess().span_bug(m.span, "expected bare rust function");
|
||||
ccx.sess().span_bug(span, "expected bare rust function");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1300,22 +1300,22 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
}
|
||||
ast_map::NodeImplItem(ref item) => {
|
||||
match **item {
|
||||
ast_map::NodeImplItem(impl_item) => {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
if contains_nodebug_attribute(&method.attrs) {
|
||||
if contains_nodebug_attribute(&impl_item.attrs) {
|
||||
return FunctionDebugContext::FunctionWithoutDebugInfo;
|
||||
}
|
||||
|
||||
(method.pe_ident(),
|
||||
(impl_item.ident,
|
||||
method.pe_fn_decl(),
|
||||
method.pe_generics(),
|
||||
method.pe_body(),
|
||||
method.span,
|
||||
impl_item.span,
|
||||
true)
|
||||
}
|
||||
ast::TypeImplItem(ref typedef) => {
|
||||
cx.sess().span_bug(typedef.span,
|
||||
ast::TypeImplItem(_) => {
|
||||
cx.sess().span_bug(impl_item.span,
|
||||
"create_function_debug_context() \
|
||||
called on associated type?!")
|
||||
}
|
||||
@ -1339,18 +1339,18 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
"create_function_debug_context: expected an expr_fn_block here")
|
||||
}
|
||||
}
|
||||
ast_map::NodeTraitItem(ref trait_method) => {
|
||||
match **trait_method {
|
||||
ast_map::NodeTraitItem(trait_item) => {
|
||||
match trait_item.node {
|
||||
ast::ProvidedMethod(ref method) => {
|
||||
if contains_nodebug_attribute(&method.attrs) {
|
||||
if contains_nodebug_attribute(&trait_item.attrs) {
|
||||
return FunctionDebugContext::FunctionWithoutDebugInfo;
|
||||
}
|
||||
|
||||
(method.pe_ident(),
|
||||
(trait_item.ident,
|
||||
method.pe_fn_decl(),
|
||||
method.pe_generics(),
|
||||
method.pe_body(),
|
||||
method.span,
|
||||
trait_item.span,
|
||||
true)
|
||||
}
|
||||
_ => {
|
||||
|
@ -42,7 +42,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
||||
ccx.tcx(), fn_id,
|
||||
Box::new(|a,b,c,d| astencode::decode_inlined_item(a, b, c, d)));
|
||||
|
||||
let inline_def = match csearch_result {
|
||||
let inline_id = match csearch_result {
|
||||
csearch::FoundAst::NotFound => {
|
||||
ccx.external().borrow_mut().insert(fn_id, None);
|
||||
return None;
|
||||
@ -88,12 +88,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
||||
None => {}
|
||||
}
|
||||
|
||||
local_def(item.id)
|
||||
item.id
|
||||
}
|
||||
csearch::FoundAst::Found(&ast::IIForeign(ref item)) => {
|
||||
ccx.external().borrow_mut().insert(fn_id, Some(item.id));
|
||||
ccx.external_srcs().borrow_mut().insert(item.id, fn_id);
|
||||
local_def(item.id)
|
||||
item.id
|
||||
}
|
||||
csearch::FoundAst::FoundParent(parent_id, &ast::IIItem(ref item)) => {
|
||||
ccx.external().borrow_mut().insert(parent_id, Some(item.id));
|
||||
@ -122,65 +122,53 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
||||
non-enum, non-struct parent")
|
||||
}
|
||||
trans_item(ccx, &**item);
|
||||
local_def(my_id)
|
||||
my_id
|
||||
}
|
||||
csearch::FoundAst::FoundParent(_, _) => {
|
||||
ccx.sess().bug("maybe_get_item_ast returned a FoundParent \
|
||||
with a non-item parent");
|
||||
}
|
||||
csearch::FoundAst::Found(&ast::IITraitItem(_, ref trait_item)) => {
|
||||
let id = match *trait_item {
|
||||
ast::ProvidedMethod(ref mth) => mth.id,
|
||||
ast::RequiredMethod(_) => ccx.sess().bug("found RequiredMethod IITraitItem"),
|
||||
ast::TypeTraitItem(_) => ccx.sess().bug("found TypeTraitItem IITraitItem"),
|
||||
};
|
||||
ccx.external().borrow_mut().insert(fn_id, Some(id));
|
||||
ccx.external_srcs().borrow_mut().insert(id, fn_id);
|
||||
ccx.external().borrow_mut().insert(fn_id, Some(trait_item.id));
|
||||
ccx.external_srcs().borrow_mut().insert(trait_item.id, fn_id);
|
||||
|
||||
ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
|
||||
|
||||
// If this is a default method, we can't look up the
|
||||
// impl type. But we aren't going to translate anyways, so
|
||||
// don't.
|
||||
local_def(id)
|
||||
trait_item.id
|
||||
}
|
||||
csearch::FoundAst::Found(&ast::IIImplItem(impl_did, ref impl_item)) => {
|
||||
let (id, monomorphic_method) = match *impl_item {
|
||||
ast::MethodImplItem(ref mth) => {
|
||||
let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
|
||||
let unparameterized = impl_tpt.generics.types.is_empty() &&
|
||||
mth.pe_generics().ty_params.is_empty();
|
||||
|
||||
(mth.id, if unparameterized { Some(mth) } else { None })
|
||||
}
|
||||
ast::TypeImplItem(_) => {
|
||||
ccx.sess().bug("found TypeImplItem IIImplItem")
|
||||
}
|
||||
};
|
||||
|
||||
ccx.external().borrow_mut().insert(fn_id, Some(id));
|
||||
ccx.external_srcs().borrow_mut().insert(id, fn_id);
|
||||
ccx.external().borrow_mut().insert(fn_id, Some(impl_item.id));
|
||||
ccx.external_srcs().borrow_mut().insert(impl_item.id, fn_id);
|
||||
|
||||
ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
|
||||
|
||||
if let Some(mth) = monomorphic_method {
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
|
||||
let llfn = get_item_val(ccx, mth.id);
|
||||
trans_fn(ccx,
|
||||
&*mth.pe_fn_decl(),
|
||||
&*mth.pe_body(),
|
||||
llfn,
|
||||
empty_substs,
|
||||
mth.id,
|
||||
&[]);
|
||||
// Use InternalLinkage so LLVM can optimize more aggressively.
|
||||
SetLinkage(llfn, InternalLinkage);
|
||||
// Translate monomorphic impl methods immediately.
|
||||
if let ast::MethodImplItem(ref mth) = impl_item.node {
|
||||
let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
|
||||
if impl_tpt.generics.types.is_empty() &&
|
||||
mth.pe_generics().ty_params.is_empty() {
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
|
||||
let llfn = get_item_val(ccx, impl_item.id);
|
||||
trans_fn(ccx,
|
||||
&*mth.pe_fn_decl(),
|
||||
&*mth.pe_body(),
|
||||
llfn,
|
||||
empty_substs,
|
||||
impl_item.id,
|
||||
&[]);
|
||||
// Use InternalLinkage so LLVM can optimize more aggressively.
|
||||
SetLinkage(llfn, InternalLinkage);
|
||||
}
|
||||
}
|
||||
local_def(id)
|
||||
|
||||
impl_item.id
|
||||
}
|
||||
};
|
||||
|
||||
return Some(inline_def);
|
||||
Some(local_def(inline_id))
|
||||
}
|
||||
|
||||
pub fn get_local_instance(ccx: &CrateContext, fn_id: ast::DefId)
|
||||
|
@ -62,14 +62,15 @@ pub fn trans_impl(ccx: &CrateContext,
|
||||
|
||||
debug!("trans_impl(name={}, id={})", name.repr(tcx), id);
|
||||
|
||||
let mut v = TransItemVisitor { ccx: ccx };
|
||||
|
||||
// Both here and below with generic methods, be sure to recurse and look for
|
||||
// items that we need to translate.
|
||||
if !generics.ty_params.is_empty() {
|
||||
let mut v = TransItemVisitor{ ccx: ccx };
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
visit::walk_method_helper(&mut v, method);
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(_) => {
|
||||
visit::walk_impl_item(&mut v, impl_item);
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
}
|
||||
@ -77,30 +78,27 @@ pub fn trans_impl(ccx: &CrateContext,
|
||||
return;
|
||||
}
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
if method.pe_generics().ty_params.len() == 0 {
|
||||
let trans_everywhere = attr::requests_inline(&method.attrs);
|
||||
let trans_everywhere = attr::requests_inline(&impl_item.attrs);
|
||||
for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) {
|
||||
let llfn = get_item_val(ccx, method.id);
|
||||
let llfn = get_item_val(ccx, impl_item.id);
|
||||
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
||||
trans_fn(ccx,
|
||||
method.pe_fn_decl(),
|
||||
method.pe_body(),
|
||||
llfn,
|
||||
empty_substs,
|
||||
method.id,
|
||||
impl_item.id,
|
||||
&[]);
|
||||
update_linkage(ccx,
|
||||
llfn,
|
||||
Some(method.id),
|
||||
Some(impl_item.id),
|
||||
if is_origin { OriginalTranslation } else { InlinedCopy });
|
||||
}
|
||||
}
|
||||
let mut v = TransItemVisitor {
|
||||
ccx: ccx,
|
||||
};
|
||||
visit::walk_method_helper(&mut v, method);
|
||||
visit::walk_impl_item(&mut v, impl_item);
|
||||
}
|
||||
ast::TypeImplItem(_) => {}
|
||||
}
|
||||
@ -190,17 +188,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
let mname = if method_id.krate == ast::LOCAL_CRATE {
|
||||
match tcx.map.get(method_id.node) {
|
||||
ast_map::NodeTraitItem(method) => {
|
||||
let ident = match *method {
|
||||
ast::RequiredMethod(ref m) => m.ident,
|
||||
ast::ProvidedMethod(ref m) => m.pe_ident(),
|
||||
ast::TypeTraitItem(_) => {
|
||||
tcx.sess.bug("trans_static_method_callee() on \
|
||||
an associated type?!")
|
||||
}
|
||||
};
|
||||
ident.name
|
||||
}
|
||||
ast_map::NodeTraitItem(trait_item) => trait_item.ident.name,
|
||||
_ => panic!("callee is not a trait method")
|
||||
}
|
||||
} else {
|
||||
|
@ -216,18 +216,18 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
d
|
||||
}
|
||||
ast_map::NodeImplItem(ii) => {
|
||||
match *ii {
|
||||
ast_map::NodeImplItem(impl_item) => {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref mth) => {
|
||||
let d = mk_lldecl(abi::Rust);
|
||||
let needs_body = setup_lldecl(d, &mth.attrs);
|
||||
let needs_body = setup_lldecl(d, &impl_item.attrs);
|
||||
if needs_body {
|
||||
trans_fn(ccx,
|
||||
mth.pe_fn_decl(),
|
||||
mth.pe_body(),
|
||||
d,
|
||||
psubsts,
|
||||
mth.id,
|
||||
impl_item.id,
|
||||
&[]);
|
||||
}
|
||||
d
|
||||
@ -237,14 +237,14 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
}
|
||||
ast_map::NodeTraitItem(method) => {
|
||||
match *method {
|
||||
ast_map::NodeTraitItem(trait_item) => {
|
||||
match trait_item.node {
|
||||
ast::ProvidedMethod(ref mth) => {
|
||||
let d = mk_lldecl(abi::Rust);
|
||||
let needs_body = setup_lldecl(d, &mth.attrs);
|
||||
let needs_body = setup_lldecl(d, &trait_item.attrs);
|
||||
if needs_body {
|
||||
trans_fn(ccx, mth.pe_fn_decl(), mth.pe_body(), d,
|
||||
psubsts, mth.id, &[]);
|
||||
psubsts, trait_item.id, &[]);
|
||||
}
|
||||
d
|
||||
}
|
||||
|
@ -1095,14 +1095,9 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
// by type collection, which may be in progress at this point.
|
||||
match this.tcx().map.expect_item(trait_did.node).node {
|
||||
ast::ItemTrait(_, _, _, ref trait_items) => {
|
||||
trait_items.iter().filter_map(|i| {
|
||||
if let ast::TypeTraitItem(ref assoc) = **i {
|
||||
if assoc.ty_param.ident.name == assoc_name {
|
||||
return Some(ast_util::local_def(assoc.ty_param.id));
|
||||
}
|
||||
}
|
||||
None
|
||||
}).next().expect("missing associated type")
|
||||
let item = trait_items.iter().find(|i| i.ident.name == assoc_name)
|
||||
.expect("missing associated type");
|
||||
ast_util::local_def(item.id)
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
|
@ -739,9 +739,10 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
|
||||
}
|
||||
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
check_method_body(ccx, &impl_pty.generics, m);
|
||||
check_method_body(ccx, &impl_pty.generics, m,
|
||||
impl_item.id, impl_item.span);
|
||||
}
|
||||
ast::TypeImplItem(_) => {
|
||||
// Nothing to do here.
|
||||
@ -750,19 +751,20 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
|
||||
}
|
||||
|
||||
}
|
||||
ast::ItemTrait(_, ref generics, _, ref trait_methods) => {
|
||||
ast::ItemTrait(_, ref generics, _, ref trait_items) => {
|
||||
check_trait_on_unimplemented(ccx, generics, it);
|
||||
let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
|
||||
for trait_method in trait_methods {
|
||||
match **trait_method {
|
||||
for trait_item in trait_items {
|
||||
match trait_item.node {
|
||||
RequiredMethod(..) => {
|
||||
// Nothing to do, since required methods don't have
|
||||
// bodies to check.
|
||||
}
|
||||
ProvidedMethod(ref m) => {
|
||||
check_method_body(ccx, &trait_def.generics, m);
|
||||
check_method_body(ccx, &trait_def.generics, m,
|
||||
trait_item.id, trait_item.span);
|
||||
}
|
||||
TypeTraitItem(_) => {
|
||||
TypeTraitItem(..) => {
|
||||
// Nothing to do.
|
||||
}
|
||||
}
|
||||
@ -855,20 +857,20 @@ fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
/// * `method`: the method definition
|
||||
fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
item_generics: &ty::Generics<'tcx>,
|
||||
method: &'tcx ast::Method) {
|
||||
debug!("check_method_body(item_generics={}, method.id={})",
|
||||
item_generics.repr(ccx.tcx),
|
||||
method.id);
|
||||
let param_env = ParameterEnvironment::for_item(ccx.tcx, method.id);
|
||||
method: &'tcx ast::Method,
|
||||
id: ast::NodeId, span: Span) {
|
||||
debug!("check_method_body(item_generics={}, id={})",
|
||||
item_generics.repr(ccx.tcx), id);
|
||||
let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
|
||||
|
||||
let fty = ty::node_id_to_type(ccx.tcx, method.id);
|
||||
let fty = ty::node_id_to_type(ccx.tcx, id);
|
||||
debug!("check_method_body: fty={}", fty.repr(ccx.tcx));
|
||||
|
||||
check_bare_fn(ccx,
|
||||
&*method.pe_fn_decl(),
|
||||
&*method.pe_body(),
|
||||
method.id,
|
||||
method.span,
|
||||
id,
|
||||
span,
|
||||
fty,
|
||||
param_env);
|
||||
}
|
||||
@ -884,9 +886,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// Check existing impl methods to see if they are both present in trait
|
||||
// and compatible with trait signature
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref impl_method) => {
|
||||
let impl_method_def_id = local_def(impl_method.id);
|
||||
let impl_method_def_id = local_def(impl_item.id);
|
||||
let impl_item_ty = ty::impl_or_trait_item(ccx.tcx,
|
||||
impl_method_def_id);
|
||||
|
||||
@ -902,7 +904,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
&ty::MethodTraitItem(ref impl_method_ty)) => {
|
||||
compare_impl_method(ccx.tcx,
|
||||
&**impl_method_ty,
|
||||
impl_method.span,
|
||||
impl_item.span,
|
||||
impl_method.pe_body().id,
|
||||
&**trait_method_ty,
|
||||
&*impl_trait_ref);
|
||||
@ -911,7 +913,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// This is span_bug as it should have already been
|
||||
// caught in resolve.
|
||||
tcx.sess.span_bug(
|
||||
impl_method.span,
|
||||
impl_item.span,
|
||||
&format!("item `{}` is of a different kind from its trait `{}`",
|
||||
token::get_name(impl_item_ty.name()),
|
||||
impl_trait_ref.repr(tcx)));
|
||||
@ -922,15 +924,15 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// This is span_bug as it should have already been
|
||||
// caught in resolve.
|
||||
tcx.sess.span_bug(
|
||||
impl_method.span,
|
||||
impl_item.span,
|
||||
&format!("method `{}` is not a member of trait `{}`",
|
||||
token::get_name(impl_item_ty.name()),
|
||||
impl_trait_ref.repr(tcx)));
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::TypeImplItem(ref typedef) => {
|
||||
let typedef_def_id = local_def(typedef.id);
|
||||
ast::TypeImplItem(_) => {
|
||||
let typedef_def_id = local_def(impl_item.id);
|
||||
let typedef_ty = ty::impl_or_trait_item(ccx.tcx,
|
||||
typedef_def_id);
|
||||
|
||||
@ -947,7 +949,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// This is `span_bug` as it should have
|
||||
// already been caught in resolve.
|
||||
tcx.sess.span_bug(
|
||||
typedef.span,
|
||||
impl_item.span,
|
||||
&format!("item `{}` is of a different kind from its trait `{}`",
|
||||
token::get_name(typedef_ty.name()),
|
||||
impl_trait_ref.repr(tcx)));
|
||||
@ -958,7 +960,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// This is `span_bug` as it should have already been
|
||||
// caught in resolve.
|
||||
tcx.sess.span_bug(
|
||||
typedef.span,
|
||||
impl_item.span,
|
||||
&format!(
|
||||
"associated type `{}` is not a member of \
|
||||
trait `{}`",
|
||||
@ -978,9 +980,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
ty::MethodTraitItem(ref trait_method) => {
|
||||
let is_implemented =
|
||||
impl_items.iter().any(|ii| {
|
||||
match **ii {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
m.pe_ident().name == trait_method.name
|
||||
match ii.node {
|
||||
ast::MethodImplItem(_) => {
|
||||
ii.ident.name == trait_method.name
|
||||
}
|
||||
ast::TypeImplItem(_) => false,
|
||||
}
|
||||
@ -993,9 +995,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
}
|
||||
ty::TypeTraitItem(ref associated_type) => {
|
||||
let is_implemented = impl_items.iter().any(|ii| {
|
||||
match **ii {
|
||||
ast::TypeImplItem(ref typedef) => {
|
||||
typedef.ident.name == associated_type.name
|
||||
match ii.node {
|
||||
ast::TypeImplItem(_) => {
|
||||
ii.ident.name == associated_type.name
|
||||
}
|
||||
ast::MethodImplItem(_) => false,
|
||||
}
|
||||
|
@ -498,28 +498,24 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
||||
visit::walk_fn(self, fk, fd, b, span)
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, t: &'v ast::TraitItem) {
|
||||
match t {
|
||||
&ast::TraitItem::ProvidedMethod(_) |
|
||||
&ast::TraitItem::TypeTraitItem(_) => {}
|
||||
&ast::TraitItem::RequiredMethod(ref method) => {
|
||||
match ty::impl_or_trait_item(self.tcx(), local_def(method.id)) {
|
||||
ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
|
||||
reject_non_type_param_bounds(
|
||||
self.tcx(),
|
||||
method.span,
|
||||
&ty_method.predicates);
|
||||
reject_shadowing_type_parameters(
|
||||
self.tcx(),
|
||||
method.span,
|
||||
&ty_method.generics);
|
||||
}
|
||||
_ => {}
|
||||
fn visit_trait_item(&mut self, trait_item: &'v ast::TraitItem) {
|
||||
if let ast::RequiredMethod(_) = trait_item.node {
|
||||
match ty::impl_or_trait_item(self.tcx(), local_def(trait_item.id)) {
|
||||
ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
|
||||
reject_non_type_param_bounds(
|
||||
self.tcx(),
|
||||
trait_item.span,
|
||||
&ty_method.predicates);
|
||||
reject_shadowing_type_parameters(
|
||||
self.tcx(),
|
||||
trait_item.span,
|
||||
&ty_method.generics);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
visit::walk_trait_item(self, t)
|
||||
visit::walk_trait_item(self, trait_item)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,20 +275,18 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||
// Converts an implementation in the AST to a vector of items.
|
||||
fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
|
||||
match item.node {
|
||||
ItemImpl(_, _, _, ref opt_trait, _, ref ast_items) => {
|
||||
ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
|
||||
let mut items: Vec<ImplOrTraitItemId> =
|
||||
ast_items.iter()
|
||||
.map(|ast_item| {
|
||||
match **ast_item {
|
||||
ast::MethodImplItem(ref ast_method) => {
|
||||
MethodTraitItemId(
|
||||
local_def(ast_method.id))
|
||||
}
|
||||
ast::TypeImplItem(ref typedef) => {
|
||||
TypeTraitItemId(local_def(typedef.id))
|
||||
}
|
||||
}
|
||||
}).collect();
|
||||
impl_items.iter().map(|impl_item| {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(_) => {
|
||||
MethodTraitItemId(local_def(impl_item.id))
|
||||
}
|
||||
ast::TypeImplItem(_) => {
|
||||
TypeTraitItemId(local_def(impl_item.id))
|
||||
}
|
||||
}
|
||||
}).collect();
|
||||
|
||||
if opt_trait.is_some() {
|
||||
let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx,
|
||||
|
@ -631,18 +631,18 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// For each method, construct a suitable ty::Method and
|
||||
// store it into the `tcx.impl_or_trait_items` table:
|
||||
for trait_item in trait_items {
|
||||
match **trait_item {
|
||||
match trait_item.node {
|
||||
ast::RequiredMethod(_) |
|
||||
ast::ProvidedMethod(_) => {
|
||||
let ty_method = Rc::new(match **trait_item {
|
||||
let ty_method = Rc::new(match trait_item.node {
|
||||
ast::RequiredMethod(ref m) => {
|
||||
ty_method_of_trait_method(
|
||||
ccx,
|
||||
trait_id,
|
||||
&trait_def.generics,
|
||||
&trait_predicates,
|
||||
&m.id,
|
||||
&m.ident.name,
|
||||
trait_item.id,
|
||||
trait_item.ident,
|
||||
&m.explicit_self,
|
||||
m.abi,
|
||||
&m.generics,
|
||||
@ -655,18 +655,15 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
trait_id,
|
||||
&trait_def.generics,
|
||||
&trait_predicates,
|
||||
&m.id,
|
||||
&m.pe_ident().name,
|
||||
trait_item.id,
|
||||
trait_item.ident,
|
||||
m.pe_explicit_self(),
|
||||
m.pe_abi(),
|
||||
m.pe_generics(),
|
||||
&m.pe_unsafety(),
|
||||
&*m.pe_fn_decl())
|
||||
}
|
||||
ast::TypeTraitItem(ref at) => {
|
||||
tcx.sess.span_bug(at.ty_param.span,
|
||||
"there shouldn't be a type trait item here")
|
||||
}
|
||||
ast::TypeTraitItem(..) => unreachable!()
|
||||
});
|
||||
|
||||
debug!("ty_method_of_trait_method yielded {} for method {} of trait {}",
|
||||
@ -680,12 +677,12 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
.borrow_mut()
|
||||
.insert(ty_method.def_id, ty::MethodTraitItem(ty_method));
|
||||
}
|
||||
ast::TypeTraitItem(ref ast_associated_type) => {
|
||||
ast::TypeTraitItem(..) => {
|
||||
let trait_did = local_def(trait_id);
|
||||
let associated_type = ty::AssociatedType {
|
||||
name: ast_associated_type.ty_param.ident.name,
|
||||
name: trait_item.ident.name,
|
||||
vis: ast::Public,
|
||||
def_id: local_def(ast_associated_type.ty_param.id),
|
||||
def_id: local_def(trait_item.id),
|
||||
container: TraitContainer(trait_did),
|
||||
};
|
||||
|
||||
@ -698,20 +695,18 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
// Add an entry mapping
|
||||
let trait_item_def_ids =
|
||||
Rc::new(trait_items.iter().map(|ti| {
|
||||
match **ti {
|
||||
ast::RequiredMethod(ref ty_method) => {
|
||||
ty::MethodTraitItemId(local_def(ty_method.id))
|
||||
}
|
||||
ast::ProvidedMethod(ref method) => {
|
||||
ty::MethodTraitItemId(local_def(method.id))
|
||||
}
|
||||
ast::TypeTraitItem(ref typedef) => {
|
||||
ty::TypeTraitItemId(local_def(typedef.ty_param.id))
|
||||
}
|
||||
let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
|
||||
let def_id = local_def(trait_item.id);
|
||||
match trait_item.node {
|
||||
ast::RequiredMethod(_) |
|
||||
ast::ProvidedMethod(_) => {
|
||||
ty::MethodTraitItemId(def_id)
|
||||
}
|
||||
}).collect());
|
||||
ast::TypeTraitItem(..) => {
|
||||
ty::TypeTraitItemId(def_id)
|
||||
}
|
||||
}
|
||||
}).collect());
|
||||
|
||||
let trait_def_id = local_def(trait_id);
|
||||
tcx.trait_item_def_ids.borrow_mut().insert(trait_def_id, trait_item_def_ids);
|
||||
@ -734,8 +729,8 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
trait_id: ast::NodeId,
|
||||
trait_generics: &ty::Generics<'tcx>,
|
||||
trait_bounds: &ty::GenericPredicates<'tcx>,
|
||||
m_id: &ast::NodeId,
|
||||
m_name: &ast::Name,
|
||||
m_id: ast::NodeId,
|
||||
m_ident: ast::Ident,
|
||||
m_explicit_self: &ast::ExplicitSelf,
|
||||
m_abi: abi::Abi,
|
||||
m_generics: &ast::Generics,
|
||||
@ -760,14 +755,14 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
};
|
||||
|
||||
ty::Method::new(
|
||||
*m_name,
|
||||
m_ident.name,
|
||||
ty_generics,
|
||||
ty_generic_predicates,
|
||||
fty,
|
||||
explicit_self_category,
|
||||
// assume public, because this is only invoked on trait methods
|
||||
ast::Public,
|
||||
local_def(*m_id),
|
||||
local_def(m_id),
|
||||
TraitContainer(local_def(trait_id)),
|
||||
None
|
||||
)
|
||||
@ -815,12 +810,13 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
trait_def: &ty::TraitDef<'tcx>,
|
||||
associated_type: &ast::AssociatedType)
|
||||
ident: ast::Ident,
|
||||
id: ast::NodeId)
|
||||
{
|
||||
let associated_type = Rc::new(ty::AssociatedType {
|
||||
name: associated_type.ty_param.ident.name,
|
||||
name: ident.name,
|
||||
vis: ast::Public,
|
||||
def_id: local_def(associated_type.ty_param.id),
|
||||
def_id: local_def(id),
|
||||
container: TraitContainer(trait_def.trait_ref.def_id),
|
||||
});
|
||||
ccx.tcx
|
||||
@ -831,12 +827,12 @@ fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
container: ImplOrTraitItemContainer,
|
||||
ms: I,
|
||||
methods: I,
|
||||
untransformed_rcvr_ty: Ty<'tcx>,
|
||||
rcvr_ty_generics: &ty::Generics<'tcx>,
|
||||
rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,
|
||||
rcvr_visibility: ast::Visibility)
|
||||
where I: Iterator<Item=&'i ast::Method>
|
||||
where I: Iterator<Item=(&'i ast::Method, ast::NodeId, ast::Ident, ast::Visibility, Span)>
|
||||
{
|
||||
debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={}, rcvr_ty_predicates={})",
|
||||
untransformed_rcvr_ty.repr(ccx.tcx),
|
||||
@ -845,24 +841,27 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
let tcx = ccx.tcx;
|
||||
let mut seen_methods = FnvHashSet();
|
||||
for m in ms {
|
||||
if !seen_methods.insert(m.pe_ident().repr(tcx)) {
|
||||
span_err!(tcx.sess, m.span, E0201, "duplicate method in trait impl");
|
||||
for (m, id, ident, vis, span) in methods {
|
||||
if !seen_methods.insert(ident.name) {
|
||||
span_err!(tcx.sess, span, E0201, "duplicate method in trait impl");
|
||||
}
|
||||
|
||||
let m_def_id = local_def(m.id);
|
||||
let m_def_id = local_def(id);
|
||||
|
||||
let mty = Rc::new(ty_of_method(ccx,
|
||||
container,
|
||||
m,
|
||||
id,
|
||||
ident,
|
||||
vis,
|
||||
untransformed_rcvr_ty,
|
||||
rcvr_ty_generics,
|
||||
rcvr_ty_predicates,
|
||||
rcvr_visibility));
|
||||
let fty = ty::mk_bare_fn(tcx, Some(m_def_id), tcx.mk_bare_fn(mty.fty.clone()));
|
||||
debug!("method {} (id {}) has type {}",
|
||||
m.pe_ident().repr(tcx),
|
||||
m.id,
|
||||
ident.repr(tcx),
|
||||
id,
|
||||
fty.repr(tcx));
|
||||
tcx.tcache.borrow_mut().insert(
|
||||
m_def_id,
|
||||
@ -872,7 +871,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
});
|
||||
tcx.predicates.borrow_mut().insert(m_def_id, mty.predicates.clone());
|
||||
|
||||
write_ty_to_tcx(tcx, m.id, fty);
|
||||
write_ty_to_tcx(tcx, id, fty);
|
||||
|
||||
debug!("writing method type: def_id={:?} mty={}",
|
||||
mty.def_id, mty.repr(ccx.tcx));
|
||||
@ -885,6 +884,9 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
fn ty_of_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
container: ImplOrTraitItemContainer,
|
||||
m: &ast::Method,
|
||||
id: ast::NodeId,
|
||||
ident: ast::Ident,
|
||||
vis: ast::Visibility,
|
||||
untransformed_rcvr_ty: Ty<'tcx>,
|
||||
rcvr_ty_generics: &ty::Generics<'tcx>,
|
||||
rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,
|
||||
@ -909,15 +911,15 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// inherit the visibility from the impl (so `foo` in `pub impl
|
||||
// { fn foo(); }` is public, but private in `priv impl { fn
|
||||
// foo(); }`).
|
||||
let method_vis = m.pe_vis().inherit_from(rcvr_visibility);
|
||||
let method_vis = vis.inherit_from(rcvr_visibility);
|
||||
|
||||
ty::Method::new(m.pe_ident().name,
|
||||
ty::Method::new(ident.name,
|
||||
m_ty_generics,
|
||||
m_ty_generic_predicates,
|
||||
fty,
|
||||
explicit_self_category,
|
||||
method_vis,
|
||||
local_def(m.id),
|
||||
local_def(id),
|
||||
container,
|
||||
None)
|
||||
}
|
||||
@ -1011,62 +1013,67 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||
it.vis
|
||||
};
|
||||
|
||||
let mut methods = Vec::new();
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
methods.push(method);
|
||||
}
|
||||
ast::TypeImplItem(ref typedef) => {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(_) => {}
|
||||
ast::TypeImplItem(ref ty) => {
|
||||
if opt_trait_ref.is_none() {
|
||||
span_err!(tcx.sess, typedef.span, E0202,
|
||||
span_err!(tcx.sess, impl_item.span, E0202,
|
||||
"associated items are not allowed in inherent impls");
|
||||
}
|
||||
|
||||
let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &*typedef.typ);
|
||||
tcx.tcache.borrow_mut().insert(local_def(typedef.id),
|
||||
let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
|
||||
tcx.tcache.borrow_mut().insert(local_def(impl_item.id),
|
||||
TypeScheme {
|
||||
generics: ty::Generics::empty(),
|
||||
ty: typ,
|
||||
});
|
||||
tcx.predicates.borrow_mut().insert(local_def(typedef.id),
|
||||
tcx.predicates.borrow_mut().insert(local_def(impl_item.id),
|
||||
ty::GenericPredicates::empty());
|
||||
write_ty_to_tcx(tcx, typedef.id, typ);
|
||||
write_ty_to_tcx(tcx, impl_item.id, typ);
|
||||
|
||||
let associated_type = Rc::new(ty::AssociatedType {
|
||||
name: typedef.ident.name,
|
||||
vis: typedef.vis,
|
||||
def_id: local_def(typedef.id),
|
||||
name: impl_item.ident.name,
|
||||
vis: impl_item.vis,
|
||||
def_id: local_def(impl_item.id),
|
||||
container: ty::ImplContainer(local_def(it.id)),
|
||||
});
|
||||
tcx.impl_or_trait_items
|
||||
.borrow_mut()
|
||||
.insert(local_def(typedef.id),
|
||||
.insert(local_def(impl_item.id),
|
||||
ty::TypeTraitItem(associated_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let methods = impl_items.iter().filter_map(|ii| {
|
||||
match ii.node {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
Some((m, ii.id, ii.ident, ii.vis, ii.span))
|
||||
}
|
||||
ast::TypeImplItem(_) => None
|
||||
}
|
||||
});
|
||||
convert_methods(ccx,
|
||||
ImplContainer(local_def(it.id)),
|
||||
methods.into_iter(),
|
||||
methods,
|
||||
selfty,
|
||||
&ty_generics,
|
||||
&ty_predicates,
|
||||
parent_visibility);
|
||||
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
match impl_item.node {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
let body_id = method.pe_body().id;
|
||||
check_method_self_type(ccx,
|
||||
&BindingRscope::new(),
|
||||
ccx.method_ty(method.id),
|
||||
ccx.method_ty(impl_item.id),
|
||||
selfty,
|
||||
method.pe_explicit_self(),
|
||||
body_id);
|
||||
}
|
||||
ast::TypeImplItem(..) => { }
|
||||
ast::TypeImplItem(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1092,15 +1099,20 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||
|
||||
debug!("convert: trait_bounds={:?}", trait_predicates);
|
||||
|
||||
let methods = trait_items.iter().filter_map(|ti| {
|
||||
match ti.node {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
Some((m, ti.id, ti.ident, ast::Inherited, ti.span))
|
||||
}
|
||||
ast::RequiredMethod(_) |
|
||||
ast::TypeTraitItem(..) => None,
|
||||
}
|
||||
});
|
||||
// Run convert_methods on the provided methods.
|
||||
let untransformed_rcvr_ty = ty::mk_self_type(tcx);
|
||||
convert_methods(ccx,
|
||||
TraitContainer(local_def(it.id)),
|
||||
trait_items.iter().filter_map(|m| match **m {
|
||||
ast::RequiredMethod(_) => None,
|
||||
ast::ProvidedMethod(ref m) => Some(m),
|
||||
ast::TypeTraitItem(_) => None,
|
||||
}),
|
||||
methods,
|
||||
untransformed_rcvr_ty,
|
||||
&trait_def.generics,
|
||||
&trait_predicates,
|
||||
@ -1115,12 +1127,12 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||
// we have a method type stored for every method.
|
||||
for trait_item in trait_items {
|
||||
let self_type = ty::mk_self_type(tcx);
|
||||
match **trait_item {
|
||||
match trait_item.node {
|
||||
ast::RequiredMethod(ref type_method) => {
|
||||
let rscope = BindingRscope::new();
|
||||
check_method_self_type(ccx,
|
||||
&rscope,
|
||||
ccx.method_ty(type_method.id),
|
||||
ccx.method_ty(trait_item.id),
|
||||
self_type,
|
||||
&type_method.explicit_self,
|
||||
it.id)
|
||||
@ -1128,15 +1140,16 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||
ast::ProvidedMethod(ref method) => {
|
||||
check_method_self_type(ccx,
|
||||
&BindingRscope::new(),
|
||||
ccx.method_ty(method.id),
|
||||
ccx.method_ty(trait_item.id),
|
||||
self_type,
|
||||
method.pe_explicit_self(),
|
||||
it.id)
|
||||
}
|
||||
ast::TypeTraitItem(ref associated_type) => {
|
||||
ast::TypeTraitItem(..) => {
|
||||
convert_associated_type(ccx,
|
||||
&*trait_def,
|
||||
associated_type);
|
||||
trait_item.ident,
|
||||
trait_item.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1348,15 +1361,12 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
|
||||
|
||||
let associated_type_names: Vec<_> =
|
||||
items.iter()
|
||||
.filter_map(|item| {
|
||||
match **item {
|
||||
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => None,
|
||||
ast::TypeTraitItem(ref data) => Some(data.ty_param.ident.name),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
|
||||
match trait_item.node {
|
||||
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => None,
|
||||
ast::TypeTraitItem(..) => Some(trait_item.ident.name),
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let trait_ref = Rc::new(ty::TraitRef {
|
||||
def_id: def_id,
|
||||
@ -1423,13 +1433,12 @@ fn trait_defines_associated_type_named(ccx: &CrateCtxt,
|
||||
_ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
|
||||
};
|
||||
|
||||
trait_items.iter()
|
||||
.any(|trait_item| {
|
||||
match *trait_item {
|
||||
ast::TypeTraitItem(ref t) => t.ty_param.ident.name == assoc_name,
|
||||
ast::RequiredMethod(..) | ast::ProvidedMethod(..) => false,
|
||||
}
|
||||
})
|
||||
trait_items.iter().any(|trait_item| {
|
||||
match trait_item.node {
|
||||
ast::TypeTraitItem(..) => trait_item.ident.name == assoc_name,
|
||||
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => false,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) {
|
||||
@ -1484,29 +1493,26 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item)
|
||||
trait_items: &[P<ast::TraitItem>])
|
||||
-> Vec<ty::Predicate<'tcx>>
|
||||
{
|
||||
trait_items
|
||||
.iter()
|
||||
.flat_map(|trait_item| {
|
||||
let assoc_type_def = match **trait_item {
|
||||
ast::TypeTraitItem(ref assoc_type) => &assoc_type.ty_param,
|
||||
ast::RequiredMethod(..) | ast::ProvidedMethod(..) => {
|
||||
return vec!().into_iter();
|
||||
}
|
||||
};
|
||||
trait_items.iter().flat_map(|trait_item| {
|
||||
let bounds = match trait_item.node {
|
||||
ast::TypeTraitItem(ref bounds, _) => bounds,
|
||||
ast::RequiredMethod(..) | ast::ProvidedMethod(..) => {
|
||||
return vec!().into_iter();
|
||||
}
|
||||
};
|
||||
|
||||
let assoc_ty = ty::mk_projection(ccx.tcx,
|
||||
self_trait_ref.clone(),
|
||||
assoc_type_def.ident.name);
|
||||
let assoc_ty = ty::mk_projection(ccx.tcx,
|
||||
self_trait_ref.clone(),
|
||||
trait_item.ident.name);
|
||||
|
||||
let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
|
||||
assoc_ty,
|
||||
&*assoc_type_def.bounds,
|
||||
SizedByDefault::Yes,
|
||||
assoc_type_def.span);
|
||||
let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
|
||||
assoc_ty,
|
||||
bounds,
|
||||
SizedByDefault::Yes,
|
||||
trait_item.span);
|
||||
|
||||
ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter()
|
||||
})
|
||||
.collect()
|
||||
ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter()
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,29 +147,13 @@ pub fn record_extern_fqn(cx: &DocContext, did: ast::DefId, kind: clean::TypeKind
|
||||
|
||||
pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
|
||||
did: ast::DefId) -> clean::Trait {
|
||||
use clean::TraitMethod;
|
||||
|
||||
let def = ty::lookup_trait_def(tcx, did);
|
||||
let trait_items = ty::trait_items(tcx, did).clean(cx);
|
||||
let provided = ty::provided_trait_methods(tcx, did);
|
||||
let items = trait_items.into_iter().map(|trait_item| {
|
||||
match trait_item.inner {
|
||||
clean::TyMethodItem(_) => {
|
||||
if provided.iter().any(|a| a.def_id == trait_item.def_id) {
|
||||
TraitMethod::ProvidedMethod(trait_item)
|
||||
} else {
|
||||
TraitMethod::RequiredMethod(trait_item)
|
||||
}
|
||||
},
|
||||
clean::AssociatedTypeItem(_) => TraitMethod::TypeTraitItem(trait_item),
|
||||
_ => unreachable!()
|
||||
}
|
||||
});
|
||||
let predicates = ty::lookup_predicates(tcx, did);
|
||||
clean::Trait {
|
||||
unsafety: def.unsafety,
|
||||
generics: (&def.generics, &predicates, subst::TypeSpace).clean(cx),
|
||||
items: items.collect(),
|
||||
items: trait_items,
|
||||
bounds: vec![], // supertraits can be found in the list of predicates
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
//! This module contains the "cleaned" pieces of the AST, and the functions
|
||||
//! that clean them.
|
||||
|
||||
pub use self::ImplMethod::*;
|
||||
pub use self::Type::*;
|
||||
pub use self::PrimitiveType::*;
|
||||
pub use self::TypeKind::*;
|
||||
@ -24,7 +23,6 @@ pub use self::Attribute::*;
|
||||
pub use self::TyParamBound::*;
|
||||
pub use self::SelfTy::*;
|
||||
pub use self::FunctionRetTy::*;
|
||||
pub use self::TraitMethod::*;
|
||||
|
||||
use syntax;
|
||||
use syntax::abi;
|
||||
@ -70,7 +68,7 @@ pub trait Clean<T> {
|
||||
fn clean(&self, cx: &DocContext) -> T;
|
||||
}
|
||||
|
||||
impl<T: Clean<U>, U> Clean<Vec<U>> for Vec<T> {
|
||||
impl<T: Clean<U>, U> Clean<Vec<U>> for [T] {
|
||||
fn clean(&self, cx: &DocContext) -> Vec<U> {
|
||||
self.iter().map(|x| x.clean(cx)).collect()
|
||||
}
|
||||
@ -339,7 +337,7 @@ pub enum ItemEnum {
|
||||
ForeignStaticItem(Static),
|
||||
MacroItem(Macro),
|
||||
PrimitiveItem(PrimitiveType),
|
||||
AssociatedTypeItem(TyParam),
|
||||
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
@ -951,8 +949,8 @@ pub struct Method {
|
||||
pub abi: abi::Abi
|
||||
}
|
||||
|
||||
impl Clean<Item> for ast::Method {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
impl Clean<Method> for ast::Method {
|
||||
fn clean(&self, cx: &DocContext) -> Method {
|
||||
let all_inputs = &self.pe_fn_decl().inputs;
|
||||
let inputs = match self.pe_explicit_self().node {
|
||||
ast::SelfStatic => &**all_inputs,
|
||||
@ -960,25 +958,17 @@ impl Clean<Item> for ast::Method {
|
||||
};
|
||||
let decl = FnDecl {
|
||||
inputs: Arguments {
|
||||
values: inputs.iter().map(|x| x.clean(cx)).collect(),
|
||||
values: inputs.clean(cx),
|
||||
},
|
||||
output: self.pe_fn_decl().output.clean(cx),
|
||||
attrs: Vec::new()
|
||||
};
|
||||
Item {
|
||||
name: Some(self.pe_ident().clean(cx)),
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.span.clean(cx),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.pe_vis().clean(cx),
|
||||
stability: get_stability(cx, ast_util::local_def(self.id)),
|
||||
inner: MethodItem(Method {
|
||||
generics: self.pe_generics().clean(cx),
|
||||
self_: self.pe_explicit_self().node.clean(cx),
|
||||
unsafety: self.pe_unsafety().clone(),
|
||||
decl: decl,
|
||||
abi: self.pe_abi()
|
||||
}),
|
||||
Method {
|
||||
generics: self.pe_generics().clean(cx),
|
||||
self_: self.pe_explicit_self().node.clean(cx),
|
||||
unsafety: self.pe_unsafety().clone(),
|
||||
decl: decl,
|
||||
abi: self.pe_abi()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -992,33 +982,25 @@ pub struct TyMethod {
|
||||
pub abi: abi::Abi
|
||||
}
|
||||
|
||||
impl Clean<Item> for ast::TypeMethod {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
impl Clean<TyMethod> for ast::TypeMethod {
|
||||
fn clean(&self, cx: &DocContext) -> TyMethod {
|
||||
let inputs = match self.explicit_self.node {
|
||||
ast::SelfStatic => &*self.decl.inputs,
|
||||
_ => &self.decl.inputs[1..]
|
||||
};
|
||||
let decl = FnDecl {
|
||||
inputs: Arguments {
|
||||
values: inputs.iter().map(|x| x.clean(cx)).collect(),
|
||||
values: inputs.clean(cx),
|
||||
},
|
||||
output: self.decl.output.clean(cx),
|
||||
attrs: Vec::new()
|
||||
};
|
||||
Item {
|
||||
name: Some(self.ident.clean(cx)),
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.span.clean(cx),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: None,
|
||||
stability: get_stability(cx, ast_util::local_def(self.id)),
|
||||
inner: TyMethodItem(TyMethod {
|
||||
unsafety: self.unsafety.clone(),
|
||||
decl: decl,
|
||||
self_: self.explicit_self.node.clean(cx),
|
||||
generics: self.generics.clean(cx),
|
||||
abi: self.abi
|
||||
}),
|
||||
TyMethod {
|
||||
unsafety: self.unsafety.clone(),
|
||||
decl: decl,
|
||||
self_: self.explicit_self.node.clean(cx),
|
||||
generics: self.generics.clean(cx),
|
||||
abi: self.abi
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1166,7 +1148,7 @@ impl Clean<FunctionRetTy> for ast::FunctionRetTy {
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Trait {
|
||||
pub unsafety: ast::Unsafety,
|
||||
pub items: Vec<TraitMethod>,
|
||||
pub items: Vec<Item>,
|
||||
pub generics: Generics,
|
||||
pub bounds: Vec<TyParamBound>,
|
||||
}
|
||||
@ -1205,64 +1187,48 @@ impl Clean<PolyTrait> for ast::PolyTraitRef {
|
||||
}
|
||||
}
|
||||
|
||||
/// An item belonging to a trait, whether a method or associated. Could be named
|
||||
/// TraitItem except that's already taken by an exported enum variant.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum TraitMethod {
|
||||
RequiredMethod(Item),
|
||||
ProvidedMethod(Item),
|
||||
TypeTraitItem(Item), // an associated type
|
||||
}
|
||||
|
||||
impl TraitMethod {
|
||||
pub fn is_req(&self) -> bool {
|
||||
match self {
|
||||
&RequiredMethod(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn is_def(&self) -> bool {
|
||||
match self {
|
||||
&ProvidedMethod(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn is_type(&self) -> bool {
|
||||
match self {
|
||||
&TypeTraitItem(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn item<'a>(&'a self) -> &'a Item {
|
||||
match *self {
|
||||
RequiredMethod(ref item) => item,
|
||||
ProvidedMethod(ref item) => item,
|
||||
TypeTraitItem(ref item) => item,
|
||||
impl Clean<Item> for ast::TraitItem {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
let inner = match self.node {
|
||||
ast::ProvidedMethod(ref m) => MethodItem(m.clean(cx)),
|
||||
ast::RequiredMethod(ref m) => TyMethodItem(m.clean(cx)),
|
||||
ast::TypeTraitItem(ref bounds, ref default) => {
|
||||
AssociatedTypeItem(bounds.clean(cx), default.clean(cx))
|
||||
}
|
||||
};
|
||||
Item {
|
||||
name: Some(self.ident.clean(cx)),
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.span.clean(cx),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: None,
|
||||
stability: get_stability(cx, ast_util::local_def(self.id)),
|
||||
inner: inner
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<TraitMethod> for ast::TraitItem {
|
||||
fn clean(&self, cx: &DocContext) -> TraitMethod {
|
||||
match self {
|
||||
&ast::RequiredMethod(ref t) => RequiredMethod(t.clean(cx)),
|
||||
&ast::ProvidedMethod(ref t) => ProvidedMethod(t.clean(cx)),
|
||||
&ast::TypeTraitItem(ref t) => TypeTraitItem(t.clean(cx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum ImplMethod {
|
||||
MethodImplItem(Item),
|
||||
TypeImplItem(Item),
|
||||
}
|
||||
|
||||
impl Clean<ImplMethod> for ast::ImplItem {
|
||||
fn clean(&self, cx: &DocContext) -> ImplMethod {
|
||||
match self {
|
||||
&ast::MethodImplItem(ref t) => MethodImplItem(t.clean(cx)),
|
||||
&ast::TypeImplItem(ref t) => TypeImplItem(t.clean(cx)),
|
||||
impl Clean<Item> for ast::ImplItem {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
let inner = match self.node {
|
||||
ast::MethodImplItem(ref m) => MethodItem(m.clean(cx)),
|
||||
ast::TypeImplItem(ref ty) => TypedefItem(Typedef {
|
||||
type_: ty.clean(cx),
|
||||
generics: Generics {
|
||||
lifetimes: Vec::new(),
|
||||
type_params: Vec::new(),
|
||||
where_predicates: Vec::new()
|
||||
},
|
||||
}),
|
||||
};
|
||||
Item {
|
||||
name: Some(self.ident.clean(cx)),
|
||||
source: self.span.clean(cx),
|
||||
attrs: self.attrs.clean(cx),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: get_stability(cx, ast_util::local_def(self.id)),
|
||||
inner: inner
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2128,12 +2094,7 @@ impl Clean<Item> for doctree::Impl {
|
||||
generics: self.generics.clean(cx),
|
||||
trait_: self.trait_.clean(cx),
|
||||
for_: self.for_.clean(cx),
|
||||
items: self.items.clean(cx).into_iter().map(|ti| {
|
||||
match ti {
|
||||
MethodImplItem(i) => i,
|
||||
TypeImplItem(i) => i,
|
||||
}
|
||||
}).collect(),
|
||||
items: self.items.clean(cx),
|
||||
derived: detect_derived(&self.attrs),
|
||||
polarity: Some(self.polarity.clean(cx)),
|
||||
}),
|
||||
@ -2500,37 +2461,15 @@ impl Clean<Stability> for attr::Stability {
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Item> for ast::AssociatedType {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
Item {
|
||||
source: self.ty_param.span.clean(cx),
|
||||
name: Some(self.ty_param.ident.clean(cx)),
|
||||
attrs: self.attrs.clean(cx),
|
||||
inner: AssociatedTypeItem(self.ty_param.clean(cx)),
|
||||
visibility: None,
|
||||
def_id: ast_util::local_def(self.ty_param.id),
|
||||
stability: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Item> for ty::AssociatedType {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
Item {
|
||||
source: DUMMY_SP.clean(cx),
|
||||
name: Some(self.name.clean(cx)),
|
||||
attrs: Vec::new(),
|
||||
inner: AssociatedTypeItem(TyParam {
|
||||
name: self.name.clean(cx),
|
||||
did: ast::DefId {
|
||||
krate: 0,
|
||||
node: ast::DUMMY_NODE_ID
|
||||
},
|
||||
// FIXME(#20727): bounds are missing and need to be filled in from the
|
||||
// predicates on the trait itself
|
||||
bounds: vec![],
|
||||
default: None,
|
||||
}),
|
||||
// FIXME(#20727): bounds are missing and need to be filled in from the
|
||||
// predicates on the trait itself
|
||||
inner: AssociatedTypeItem(vec![], None),
|
||||
visibility: None,
|
||||
def_id: self.def_id,
|
||||
stability: None,
|
||||
@ -2538,27 +2477,6 @@ impl Clean<Item> for ty::AssociatedType {
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Item> for ast::Typedef {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
Item {
|
||||
source: self.span.clean(cx),
|
||||
name: Some(self.ident.clean(cx)),
|
||||
attrs: self.attrs.clean(cx),
|
||||
inner: TypedefItem(Typedef {
|
||||
type_: self.typ.clean(cx),
|
||||
generics: Generics {
|
||||
lifetimes: Vec::new(),
|
||||
type_params: Vec::new(),
|
||||
where_predicates: Vec::new()
|
||||
},
|
||||
}),
|
||||
visibility: None,
|
||||
def_id: ast_util::local_def(self.id),
|
||||
stability: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ty::GenericPredicates<'a>, ParamSpace) {
|
||||
fn clean(&self, cx: &DocContext) -> Typedef {
|
||||
let (ref ty_scheme, ref predicates, ps) = *self;
|
||||
|
@ -40,37 +40,13 @@ pub trait DocFolder : Sized {
|
||||
EnumItem(i)
|
||||
},
|
||||
TraitItem(mut i) => {
|
||||
fn vtrm<T: DocFolder>(this: &mut T, trm: TraitMethod)
|
||||
-> Option<TraitMethod> {
|
||||
match trm {
|
||||
RequiredMethod(it) => {
|
||||
match this.fold_item(it) {
|
||||
Some(x) => return Some(RequiredMethod(x)),
|
||||
None => return None,
|
||||
}
|
||||
},
|
||||
ProvidedMethod(it) => {
|
||||
match this.fold_item(it) {
|
||||
Some(x) => return Some(ProvidedMethod(x)),
|
||||
None => return None,
|
||||
}
|
||||
},
|
||||
TypeTraitItem(it) => {
|
||||
match this.fold_item(it) {
|
||||
Some(x) => return Some(TypeTraitItem(x)),
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
|
||||
i.items.extend(foo.into_iter().filter_map(|x| vtrm(self, x)));
|
||||
i.items.extend(foo.into_iter().filter_map(|x| self.fold_item(x)));
|
||||
TraitItem(i)
|
||||
},
|
||||
ImplItem(mut i) => {
|
||||
let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
|
||||
i.items.extend(foo.into_iter()
|
||||
.filter_map(|x| self.fold_item(x)));
|
||||
i.items.extend(foo.into_iter().filter_map(|x| self.fold_item(x)));
|
||||
ImplItem(i)
|
||||
},
|
||||
VariantItem(i) => {
|
||||
|
@ -1685,9 +1685,15 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
bounds,
|
||||
WhereClause(&t.generics)));
|
||||
|
||||
let types = t.items.iter().filter(|m| m.is_type()).collect::<Vec<_>>();
|
||||
let required = t.items.iter().filter(|m| m.is_req()).collect::<Vec<_>>();
|
||||
let provided = t.items.iter().filter(|m| m.is_def()).collect::<Vec<_>>();
|
||||
let types = t.items.iter().filter(|m| {
|
||||
match m.inner { clean::AssociatedTypeItem(..) => true, _ => false }
|
||||
}).collect::<Vec<_>>();
|
||||
let required = t.items.iter().filter(|m| {
|
||||
match m.inner { clean::TyMethodItem(_) => true, _ => false }
|
||||
}).collect::<Vec<_>>();
|
||||
let provided = t.items.iter().filter(|m| {
|
||||
match m.inner { clean::MethodItem(_) => true, _ => false }
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
if t.items.len() == 0 {
|
||||
try!(write!(w, "{{ }}"));
|
||||
@ -1695,7 +1701,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
try!(write!(w, "{{\n"));
|
||||
for t in &types {
|
||||
try!(write!(w, " "));
|
||||
try!(render_method(w, t.item()));
|
||||
try!(render_method(w, t));
|
||||
try!(write!(w, ";\n"));
|
||||
}
|
||||
if types.len() > 0 && required.len() > 0 {
|
||||
@ -1703,7 +1709,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
}
|
||||
for m in &required {
|
||||
try!(write!(w, " "));
|
||||
try!(render_method(w, m.item()));
|
||||
try!(render_method(w, m));
|
||||
try!(write!(w, ";\n"));
|
||||
}
|
||||
if required.len() > 0 && provided.len() > 0 {
|
||||
@ -1711,7 +1717,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
}
|
||||
for m in &provided {
|
||||
try!(write!(w, " "));
|
||||
try!(render_method(w, m.item()));
|
||||
try!(render_method(w, m));
|
||||
try!(write!(w, " {{ ... }}\n"));
|
||||
}
|
||||
try!(write!(w, "}}"));
|
||||
@ -1721,15 +1727,15 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
// Trait documentation
|
||||
try!(document(w, it));
|
||||
|
||||
fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitMethod)
|
||||
fn trait_item(w: &mut fmt::Formatter, m: &clean::Item)
|
||||
-> fmt::Result {
|
||||
try!(write!(w, "<h3 id='{}.{}' class='method'>{}<code>",
|
||||
shortty(m.item()),
|
||||
*m.item().name.as_ref().unwrap(),
|
||||
ConciseStability(&m.item().stability)));
|
||||
try!(render_method(w, m.item()));
|
||||
shortty(m),
|
||||
*m.name.as_ref().unwrap(),
|
||||
ConciseStability(&m.stability)));
|
||||
try!(render_method(w, m));
|
||||
try!(write!(w, "</code></h3>"));
|
||||
try!(document(w, m.item()));
|
||||
try!(document(w, m));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -1798,12 +1804,14 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
}
|
||||
|
||||
fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
|
||||
typ: &clean::TyParam) -> fmt::Result {
|
||||
bounds: &Vec<clean::TyParamBound>,
|
||||
default: &Option<clean::Type>)
|
||||
-> fmt::Result {
|
||||
try!(write!(w, "type {}", it.name.as_ref().unwrap()));
|
||||
if typ.bounds.len() > 0 {
|
||||
try!(write!(w, ": {}", TyParamBounds(&*typ.bounds)))
|
||||
if bounds.len() > 0 {
|
||||
try!(write!(w, ": {}", TyParamBounds(bounds)))
|
||||
}
|
||||
if let Some(ref default) = typ.default {
|
||||
if let Some(ref default) = *default {
|
||||
try!(write!(w, " = {}", default));
|
||||
}
|
||||
Ok(())
|
||||
@ -1839,8 +1847,8 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
|
||||
clean::MethodItem(ref m) => {
|
||||
method(w, meth, m.unsafety, m.abi, &m.generics, &m.self_, &m.decl)
|
||||
}
|
||||
clean::AssociatedTypeItem(ref typ) => {
|
||||
assoc_type(w, meth, typ)
|
||||
clean::AssociatedTypeItem(ref bounds, ref default) => {
|
||||
assoc_type(w, meth, bounds, default)
|
||||
}
|
||||
_ => panic!("render_method called on non-method")
|
||||
}
|
||||
@ -2138,13 +2146,13 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
|
||||
try!(write!(w, "type {} = {}", name, tydef.type_));
|
||||
try!(write!(w, "</code></h4>\n"));
|
||||
}
|
||||
clean::AssociatedTypeItem(ref typaram) => {
|
||||
clean::AssociatedTypeItem(ref bounds, ref default) => {
|
||||
let name = item.name.as_ref().unwrap();
|
||||
try!(write!(w, "<h4 id='assoc_type.{}' class='{}'>{}<code>",
|
||||
*name,
|
||||
shortty(item),
|
||||
ConciseStability(&item.stability)));
|
||||
try!(assoc_type(w, item, typaram));
|
||||
try!(assoc_type(w, item, bounds, default));
|
||||
try!(write!(w, "</code></h4>\n"));
|
||||
}
|
||||
_ => panic!("can't make docs for trait item with name {:?}", item.name)
|
||||
@ -2167,13 +2175,13 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
|
||||
t: &clean::Trait,
|
||||
i: &clean::Impl) -> fmt::Result {
|
||||
for trait_item in &t.items {
|
||||
let n = trait_item.item().name.clone();
|
||||
let n = trait_item.name.clone();
|
||||
match i.items.iter().find(|m| { m.name == n }) {
|
||||
Some(..) => continue,
|
||||
None => {}
|
||||
}
|
||||
|
||||
try!(doctraititem(w, trait_item.item(), false));
|
||||
try!(doctraititem(w, trait_item, false));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -20,8 +20,8 @@ use syntax::attr::{Unstable, Stable};
|
||||
use syntax::ast::Public;
|
||||
|
||||
use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
|
||||
use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
|
||||
use clean::{TypeTraitItem, ExternCrateItem, ImportItem, PrimitiveItem, Stability};
|
||||
use clean::{ImplItem, Impl, Trait, TraitItem};
|
||||
use clean::{ExternCrateItem, ImportItem, PrimitiveItem, Stability};
|
||||
|
||||
use html::render::cache;
|
||||
|
||||
@ -140,11 +140,11 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
|
||||
// considered to have no children.
|
||||
match item.inner {
|
||||
// Require explicit `pub` to be visible
|
||||
ImplItem(Impl { items: ref subitems, trait_: None, .. }) => {
|
||||
let subcounts = subitems.iter().filter(|i| visible(*i))
|
||||
.map(summarize_item)
|
||||
.map(|s| s.0)
|
||||
.fold(Counts::zero(), |acc, x| acc + x);
|
||||
ImplItem(Impl { ref items, trait_: None, .. }) => {
|
||||
let subcounts = items.iter().filter(|i| visible(*i))
|
||||
.map(summarize_item)
|
||||
.map(|s| s.0)
|
||||
.fold(Counts::zero(), |acc, x| acc + x);
|
||||
(subcounts, None)
|
||||
}
|
||||
// `pub` automatically
|
||||
@ -154,22 +154,10 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
|
||||
.fold(Counts::zero(), |acc, x| acc + x);
|
||||
(item_counts + subcounts, None)
|
||||
}
|
||||
TraitItem(Trait {
|
||||
items: ref trait_items,
|
||||
..
|
||||
}) => {
|
||||
fn extract_item<'a>(trait_item: &'a TraitMethod) -> &'a Item {
|
||||
match *trait_item {
|
||||
ProvidedMethod(ref item) |
|
||||
RequiredMethod(ref item) |
|
||||
TypeTraitItem(ref item) => item
|
||||
}
|
||||
}
|
||||
let subcounts = trait_items.iter()
|
||||
.map(extract_item)
|
||||
.map(summarize_item)
|
||||
.map(|s| s.0)
|
||||
.fold(Counts::zero(), |acc, x| acc + x);
|
||||
TraitItem(Trait { ref items, .. }) => {
|
||||
let subcounts = items.iter().map(summarize_item)
|
||||
.map(|s| s.0)
|
||||
.fold(Counts::zero(), |acc, x| acc + x);
|
||||
(item_counts + subcounts, None)
|
||||
}
|
||||
ModuleItem(Module { ref items, .. }) => {
|
||||
|
@ -22,7 +22,7 @@ pub use self::Expr_::*;
|
||||
pub use self::FloatTy::*;
|
||||
pub use self::FunctionRetTy::*;
|
||||
pub use self::ForeignItem_::*;
|
||||
pub use self::ImplItem::*;
|
||||
pub use self::ImplItem_::*;
|
||||
pub use self::InlinedItem::*;
|
||||
pub use self::IntTy::*;
|
||||
pub use self::Item_::*;
|
||||
@ -33,7 +33,7 @@ pub use self::LocalSource::*;
|
||||
pub use self::Mac_::*;
|
||||
pub use self::MacStmtStyle::*;
|
||||
pub use self::MetaItem_::*;
|
||||
pub use self::Method_::*;
|
||||
pub use self::Method::*;
|
||||
pub use self::Mutability::*;
|
||||
pub use self::Pat_::*;
|
||||
pub use self::PathListItem_::*;
|
||||
@ -44,7 +44,7 @@ pub use self::Stmt_::*;
|
||||
pub use self::StrStyle::*;
|
||||
pub use self::StructFieldKind::*;
|
||||
pub use self::TokenTree::*;
|
||||
pub use self::TraitItem::*;
|
||||
pub use self::TraitItem_::*;
|
||||
pub use self::Ty_::*;
|
||||
pub use self::TyParamBound::*;
|
||||
pub use self::UintTy::*;
|
||||
@ -1062,16 +1062,11 @@ pub struct TypeField {
|
||||
/// one without a default implementation
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct TypeMethod {
|
||||
pub ident: Ident,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub unsafety: Unsafety,
|
||||
pub abi: Abi,
|
||||
pub decl: P<FnDecl>,
|
||||
pub generics: Generics,
|
||||
pub explicit_self: ExplicitSelf,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
}
|
||||
|
||||
/// Represents a method declaration in a trait declaration, possibly including
|
||||
@ -1079,32 +1074,35 @@ pub struct TypeMethod {
|
||||
/// doesn't have an implementation, just a signature) or provided (meaning it
|
||||
/// has a default implementation).
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum TraitItem {
|
||||
pub struct TraitItem {
|
||||
pub id: NodeId,
|
||||
pub ident: Ident,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub node: TraitItem_,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum TraitItem_ {
|
||||
RequiredMethod(TypeMethod),
|
||||
ProvidedMethod(Method),
|
||||
TypeTraitItem(AssociatedType),
|
||||
TypeTraitItem(TyParamBounds, Option<P<Ty>>),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum ImplItem {
|
||||
MethodImplItem(Method),
|
||||
TypeImplItem(Typedef),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct AssociatedType {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub ty_param: TyParam,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct Typedef {
|
||||
pub struct ImplItem {
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub ident: Ident,
|
||||
pub vis: Visibility,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub typ: P<Ty>,
|
||||
pub node: ImplItem_,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum ImplItem_ {
|
||||
MethodImplItem(Method),
|
||||
TypeImplItem(P<Ty>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
|
||||
@ -1419,24 +1417,14 @@ pub enum ExplicitSelf_ {
|
||||
pub type ExplicitSelf = Spanned<ExplicitSelf_>;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct Method {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub node: Method_,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum Method_ {
|
||||
pub enum Method {
|
||||
/// Represents a method declaration
|
||||
MethDecl(Ident,
|
||||
Generics,
|
||||
MethDecl(Generics,
|
||||
Abi,
|
||||
ExplicitSelf,
|
||||
Unsafety,
|
||||
P<FnDecl>,
|
||||
P<Block>,
|
||||
Visibility),
|
||||
P<Block>),
|
||||
/// Represents a macro in method position
|
||||
MethMac(Mac),
|
||||
}
|
||||
@ -1726,8 +1714,8 @@ impl ForeignItem_ {
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum InlinedItem {
|
||||
IIItem(P<Item>),
|
||||
IITraitItem(DefId /* impl id */, TraitItem),
|
||||
IIImplItem(DefId /* impl id */, ImplItem),
|
||||
IITraitItem(DefId /* impl id */, P<TraitItem>),
|
||||
IIImplItem(DefId /* impl id */, P<ImplItem>),
|
||||
IIForeign(P<ForeignItem>),
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ impl MaybeFnLike for ast::Item {
|
||||
|
||||
impl MaybeFnLike for ast::TraitItem {
|
||||
fn is_fn_like(&self) -> bool {
|
||||
match *self { ast::ProvidedMethod(_) => true, _ => false, }
|
||||
match self.node { ast::ProvidedMethod(_) => true, _ => false, }
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,25 +156,25 @@ impl<'a> FnLikeNode<'a> {
|
||||
|
||||
pub fn body(self) -> &'a Block {
|
||||
self.handle(|i: ItemFnParts<'a>| &*i.body,
|
||||
|m: &'a ast::Method| m.pe_body(),
|
||||
|_, _, m: &'a ast::Method, _| m.pe_body(),
|
||||
|c: ClosureParts<'a>| c.body)
|
||||
}
|
||||
|
||||
pub fn decl(self) -> &'a FnDecl {
|
||||
self.handle(|i: ItemFnParts<'a>| &*i.decl,
|
||||
|m: &'a ast::Method| m.pe_fn_decl(),
|
||||
|_, _, m: &'a ast::Method, _| m.pe_fn_decl(),
|
||||
|c: ClosureParts<'a>| c.decl)
|
||||
}
|
||||
|
||||
pub fn span(self) -> Span {
|
||||
self.handle(|i: ItemFnParts| i.span,
|
||||
|m: &'a ast::Method| m.span,
|
||||
|_, _, _: &'a ast::Method, span| span,
|
||||
|c: ClosureParts| c.span)
|
||||
}
|
||||
|
||||
pub fn id(self) -> NodeId {
|
||||
self.handle(|i: ItemFnParts| i.id,
|
||||
|m: &'a ast::Method| m.id,
|
||||
|id, _, _: &'a ast::Method, _| id,
|
||||
|c: ClosureParts| c.id)
|
||||
}
|
||||
|
||||
@ -185,15 +185,15 @@ impl<'a> FnLikeNode<'a> {
|
||||
let closure = |_: ClosureParts| {
|
||||
visit::FkFnBlock
|
||||
};
|
||||
let method = |m: &'a ast::Method| {
|
||||
visit::FkMethod(m.pe_ident(), m.pe_generics(), m)
|
||||
let method = |_, ident, m: &'a ast::Method, _| {
|
||||
visit::FkMethod(ident, m)
|
||||
};
|
||||
self.handle(item, method, closure)
|
||||
}
|
||||
|
||||
fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
|
||||
I: FnOnce(ItemFnParts<'a>) -> A,
|
||||
M: FnOnce(&'a ast::Method) -> A,
|
||||
M: FnOnce(NodeId, ast::Ident, &'a ast::Method, Span) -> A,
|
||||
C: FnOnce(ClosureParts<'a>) -> A,
|
||||
{
|
||||
match self.node {
|
||||
@ -205,13 +205,13 @@ impl<'a> FnLikeNode<'a> {
|
||||
}),
|
||||
_ => panic!("item FnLikeNode that is not fn-like"),
|
||||
},
|
||||
ast_map::NodeTraitItem(t) => match *t {
|
||||
ast::ProvidedMethod(ref m) => method(m),
|
||||
ast_map::NodeTraitItem(ti) => match ti.node {
|
||||
ast::ProvidedMethod(ref m) => method(ti.id, ti.ident, m, ti.span),
|
||||
_ => panic!("trait method FnLikeNode that is not fn-like"),
|
||||
},
|
||||
ast_map::NodeImplItem(ii) => {
|
||||
match *ii {
|
||||
ast::MethodImplItem(ref m) => method(m),
|
||||
match ii.node {
|
||||
ast::MethodImplItem(ref m) => method(ii.id, ii.ident, m, ii.span),
|
||||
ast::TypeImplItem(_) => {
|
||||
panic!("impl method FnLikeNode that is not fn-like")
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use self::MapEntry::*;
|
||||
|
||||
use abi;
|
||||
use ast::*;
|
||||
use ast_util::{self, PostExpansionMethod};
|
||||
use ast_util;
|
||||
use codemap::{DUMMY_SP, Span, Spanned};
|
||||
use fold::Folder;
|
||||
use parse::token;
|
||||
@ -374,35 +374,8 @@ impl<'ast> Map<'ast> {
|
||||
}
|
||||
}
|
||||
NodeForeignItem(i) => PathName(i.ident.name),
|
||||
NodeImplItem(ii) => {
|
||||
match *ii {
|
||||
MethodImplItem(ref m) => {
|
||||
match m.node {
|
||||
MethDecl(ident, _, _, _, _, _, _, _) => {
|
||||
PathName(ident.name)
|
||||
}
|
||||
MethMac(_) => {
|
||||
panic!("no path elem for {:?}", node)
|
||||
}
|
||||
}
|
||||
}
|
||||
TypeImplItem(ref t) => PathName(t.ident.name),
|
||||
}
|
||||
},
|
||||
NodeTraitItem(tm) => match *tm {
|
||||
RequiredMethod(ref m) => PathName(m.ident.name),
|
||||
ProvidedMethod(ref m) => {
|
||||
match m.node {
|
||||
MethDecl(ident, _, _, _, _, _, _, _) => {
|
||||
PathName(ident.name)
|
||||
}
|
||||
MethMac(_) => panic!("no path elem for {:?}", node),
|
||||
}
|
||||
}
|
||||
TypeTraitItem(ref m) => {
|
||||
PathName(m.ty_param.ident.name)
|
||||
}
|
||||
},
|
||||
NodeImplItem(ii) => PathName(ii.ident.name),
|
||||
NodeTraitItem(ti) => PathName(ti.ident.name),
|
||||
NodeVariant(v) => PathName(v.node.name.name),
|
||||
_ => panic!("no path elem for {:?}", node)
|
||||
}
|
||||
@ -458,21 +431,12 @@ impl<'ast> Map<'ast> {
|
||||
|
||||
/// Given a node ID, get a list of of attributes associated with the AST
|
||||
/// corresponding to the Node ID
|
||||
pub fn attrs(&self, id: NodeId) -> &[Attribute] {
|
||||
pub fn attrs(&self, id: NodeId) -> &'ast [Attribute] {
|
||||
let attrs = match self.find(id) {
|
||||
Some(NodeItem(i)) => Some(&i.attrs[..]),
|
||||
Some(NodeForeignItem(fi)) => Some(&fi.attrs[..]),
|
||||
Some(NodeTraitItem(ref tm)) => match **tm {
|
||||
RequiredMethod(ref type_m) => Some(&type_m.attrs[..]),
|
||||
ProvidedMethod(ref m) => Some(&m.attrs[..]),
|
||||
TypeTraitItem(ref typ) => Some(&typ.attrs[..]),
|
||||
},
|
||||
Some(NodeImplItem(ref ii)) => {
|
||||
match **ii {
|
||||
MethodImplItem(ref m) => Some(&m.attrs[..]),
|
||||
TypeImplItem(ref t) => Some(&t.attrs[..]),
|
||||
}
|
||||
}
|
||||
Some(NodeTraitItem(ref ti)) => Some(&ti.attrs[..]),
|
||||
Some(NodeImplItem(ref ii)) => Some(&ii.attrs[..]),
|
||||
Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]),
|
||||
// unit/tuple structs take the attributes straight from
|
||||
// the struct definition.
|
||||
@ -505,19 +469,8 @@ impl<'ast> Map<'ast> {
|
||||
let sp = match self.find(id) {
|
||||
Some(NodeItem(item)) => item.span,
|
||||
Some(NodeForeignItem(foreign_item)) => foreign_item.span,
|
||||
Some(NodeTraitItem(trait_method)) => {
|
||||
match *trait_method {
|
||||
RequiredMethod(ref type_method) => type_method.span,
|
||||
ProvidedMethod(ref method) => method.span,
|
||||
TypeTraitItem(ref typedef) => typedef.ty_param.span,
|
||||
}
|
||||
}
|
||||
Some(NodeImplItem(ref impl_item)) => {
|
||||
match **impl_item {
|
||||
MethodImplItem(ref method) => method.span,
|
||||
TypeImplItem(ref typedef) => typedef.span,
|
||||
}
|
||||
}
|
||||
Some(NodeTraitItem(trait_method)) => trait_method.span,
|
||||
Some(NodeImplItem(ref impl_item)) => impl_item.span,
|
||||
Some(NodeVariant(variant)) => variant.span,
|
||||
Some(NodeExpr(expr)) => expr.span,
|
||||
Some(NodeStmt(stmt)) => stmt.span,
|
||||
@ -650,31 +603,8 @@ impl<T:Named> Named for Spanned<T> { fn name(&self) -> Name { self.node.name() }
|
||||
impl Named for Item { fn name(&self) -> Name { self.ident.name } }
|
||||
impl Named for ForeignItem { fn name(&self) -> Name { self.ident.name } }
|
||||
impl Named for Variant_ { fn name(&self) -> Name { self.name.name } }
|
||||
impl Named for TraitItem {
|
||||
fn name(&self) -> Name {
|
||||
match *self {
|
||||
RequiredMethod(ref tm) => tm.ident.name,
|
||||
ProvidedMethod(ref m) => m.name(),
|
||||
TypeTraitItem(ref at) => at.ty_param.ident.name,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Named for ImplItem {
|
||||
fn name(&self) -> Name {
|
||||
match *self {
|
||||
MethodImplItem(ref m) => m.name(),
|
||||
TypeImplItem(ref td) => td.ident.name,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Named for Method {
|
||||
fn name(&self) -> Name {
|
||||
match self.node {
|
||||
MethDecl(i, _, _, _, _, _, _, _) => i.name,
|
||||
MethMac(_) => panic!("encountered unexpanded method macro."),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } }
|
||||
impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
|
||||
|
||||
pub trait FoldOps {
|
||||
fn new_id(&self, id: NodeId) -> NodeId {
|
||||
@ -739,12 +669,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
self.parent = i.id;
|
||||
match i.node {
|
||||
ItemImpl(_, _, _, _, _, ref impl_items) => {
|
||||
for impl_item in impl_items {
|
||||
let id = match **impl_item {
|
||||
MethodImplItem(ref m) => m.id,
|
||||
TypeImplItem(ref t) => t.id,
|
||||
};
|
||||
self.insert(id, NodeImplItem(impl_item));
|
||||
for ii in impl_items {
|
||||
self.insert(ii.id, NodeImplItem(ii));
|
||||
}
|
||||
}
|
||||
ItemEnum(ref enum_definition, _) => {
|
||||
@ -773,13 +699,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
for tm in trait_items {
|
||||
let id = match **tm {
|
||||
RequiredMethod(ref m) => m.id,
|
||||
ProvidedMethod(ref m) => m.id,
|
||||
TypeTraitItem(ref typ) => typ.ty_param.id,
|
||||
};
|
||||
self.insert(id, NodeTraitItem(tm));
|
||||
for ti in trait_items {
|
||||
self.insert(ti.id, NodeTraitItem(ti));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -788,6 +709,20 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
self.parent = parent;
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
|
||||
let parent = self.parent;
|
||||
self.parent = ti.id;
|
||||
visit::walk_trait_item(self, ti);
|
||||
self.parent = parent;
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
|
||||
let parent = self.parent;
|
||||
self.parent = ii.id;
|
||||
visit::walk_impl_item(self, ii);
|
||||
self.parent = parent;
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &'ast Pat) {
|
||||
self.insert(pat.id, match pat.node {
|
||||
// Note: this is at least *potentially* a pattern...
|
||||
@ -807,29 +742,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
visit::walk_stmt(self, stmt);
|
||||
}
|
||||
|
||||
fn visit_ty_method(&mut self, m: &'ast TypeMethod) {
|
||||
let parent = self.parent;
|
||||
self.parent = m.id;
|
||||
self.visit_fn_decl(&*m.decl);
|
||||
visit::walk_ty_method(self, m);
|
||||
self.parent = parent;
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl,
|
||||
b: &'ast Block, s: Span, id: NodeId) {
|
||||
match fk {
|
||||
visit::FkMethod(..) => {
|
||||
let parent = self.parent;
|
||||
self.parent = id;
|
||||
self.visit_fn_decl(fd);
|
||||
visit::walk_fn(self, fk, fd, b, s);
|
||||
self.parent = parent;
|
||||
}
|
||||
_ => {
|
||||
self.visit_fn_decl(fd);
|
||||
visit::walk_fn(self, fk, fd, b, s);
|
||||
}
|
||||
}
|
||||
b: &'ast Block, s: Span, _: NodeId) {
|
||||
self.visit_fn_decl(fd);
|
||||
visit::walk_fn(self, fk, fd, b, s);
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &'ast Ty) {
|
||||
@ -911,33 +827,14 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
|
||||
let mut fld = IdAndSpanUpdater { fold_ops: fold_ops };
|
||||
let ii = match ii {
|
||||
IIItem(i) => IIItem(fld.fold_item(i).expect_one("expected one item")),
|
||||
IITraitItem(d, ti) => match ti {
|
||||
ProvidedMethod(m) => {
|
||||
IITraitItem(fld.fold_ops.new_def_id(d),
|
||||
ProvidedMethod(fld.fold_method(m)
|
||||
.expect_one("expected one method")))
|
||||
}
|
||||
RequiredMethod(ty_m) => {
|
||||
IITraitItem(fld.fold_ops.new_def_id(d),
|
||||
RequiredMethod(fld.fold_type_method(ty_m)))
|
||||
}
|
||||
TypeTraitItem(at) => {
|
||||
IITraitItem(
|
||||
fld.fold_ops.new_def_id(d),
|
||||
TypeTraitItem(fld.fold_associated_type(at)))
|
||||
}
|
||||
},
|
||||
IIImplItem(d, m) => match m {
|
||||
MethodImplItem(m) => {
|
||||
IIImplItem(fld.fold_ops.new_def_id(d),
|
||||
MethodImplItem(fld.fold_method(m)
|
||||
.expect_one("expected one method")))
|
||||
}
|
||||
TypeImplItem(t) => {
|
||||
IIImplItem(fld.fold_ops.new_def_id(d),
|
||||
TypeImplItem(fld.fold_typedef(t)))
|
||||
}
|
||||
},
|
||||
IITraitItem(d, ti) => {
|
||||
IITraitItem(fld.fold_ops.new_def_id(d),
|
||||
fld.fold_trait_item(ti).expect_one("expected one trait item"))
|
||||
}
|
||||
IIImplItem(d, ii) => {
|
||||
IIImplItem(fld.fold_ops.new_def_id(d),
|
||||
fld.fold_impl_item(ii).expect_one("expected one impl item"))
|
||||
}
|
||||
IIForeign(i) => IIForeign(fld.fold_foreign_item(i))
|
||||
};
|
||||
|
||||
@ -959,25 +856,14 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
|
||||
// add it to the table now. Likewise with foreign items.
|
||||
match ii_parent.ii {
|
||||
IIItem(_) => {}
|
||||
IITraitItem(_, ref trait_item) => {
|
||||
let trait_item_id = match *trait_item {
|
||||
ProvidedMethod(ref m) => m.id,
|
||||
RequiredMethod(ref m) => m.id,
|
||||
TypeTraitItem(ref ty) => ty.ty_param.id,
|
||||
};
|
||||
|
||||
collector.insert(trait_item_id, NodeTraitItem(trait_item));
|
||||
IITraitItem(_, ref ti) => {
|
||||
collector.insert(ti.id, NodeTraitItem(ti));
|
||||
}
|
||||
IIImplItem(_, ref impl_item) => {
|
||||
let impl_item_id = match *impl_item {
|
||||
MethodImplItem(ref m) => m.id,
|
||||
TypeImplItem(ref ti) => ti.id,
|
||||
};
|
||||
|
||||
collector.insert(impl_item_id, NodeImplItem(impl_item));
|
||||
IIImplItem(_, ref ii) => {
|
||||
collector.insert(ii.id, NodeImplItem(ii));
|
||||
}
|
||||
IIForeign(ref i) => {
|
||||
collector.insert(i.id, NodeForeignItem(&**i));
|
||||
collector.insert(i.id, NodeForeignItem(i));
|
||||
}
|
||||
}
|
||||
*map.map.borrow_mut() = collector.map;
|
||||
@ -993,8 +879,8 @@ impl<'a> NodePrinter for pprust::State<'a> {
|
||||
match *node {
|
||||
NodeItem(a) => self.print_item(&*a),
|
||||
NodeForeignItem(a) => self.print_foreign_item(&*a),
|
||||
NodeTraitItem(a) => self.print_trait_method(&*a),
|
||||
NodeImplItem(a) => self.print_impl_item(&*a),
|
||||
NodeTraitItem(a) => self.print_trait_item(a),
|
||||
NodeImplItem(a) => self.print_impl_item(a),
|
||||
NodeVariant(a) => self.print_variant(&*a),
|
||||
NodeExpr(a) => self.print_expr(&*a),
|
||||
NodeStmt(a) => self.print_stmt(&*a),
|
||||
@ -1041,48 +927,39 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
|
||||
let path_str = map.path_to_str_with_ident(id, item.ident);
|
||||
format!("foreign item {}{}", path_str, id_str)
|
||||
}
|
||||
Some(NodeImplItem(ref ii)) => {
|
||||
match **ii {
|
||||
Some(NodeImplItem(ii)) => {
|
||||
match ii.node {
|
||||
MethodImplItem(ref m) => {
|
||||
match m.node {
|
||||
MethDecl(ident, _, _, _, _, _, _, _) =>
|
||||
match *m {
|
||||
MethDecl(..) =>
|
||||
format!("method {} in {}{}",
|
||||
token::get_ident(ident),
|
||||
token::get_ident(ii.ident),
|
||||
map.path_to_string(id), id_str),
|
||||
MethMac(ref mac) =>
|
||||
format!("method macro {}{}",
|
||||
pprust::mac_to_string(mac), id_str)
|
||||
}
|
||||
}
|
||||
TypeImplItem(ref t) => {
|
||||
TypeImplItem(_) => {
|
||||
format!("assoc type {} in {}{}",
|
||||
token::get_ident(t.ident),
|
||||
token::get_ident(ii.ident),
|
||||
map.path_to_string(id),
|
||||
id_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(NodeTraitItem(ref tm)) => {
|
||||
match **tm {
|
||||
RequiredMethod(ref m) => {
|
||||
format!("required method {} in {}{}",
|
||||
token::get_ident(m.ident),
|
||||
map.path_to_string(id),
|
||||
id_str)
|
||||
}
|
||||
ProvidedMethod(ref m) => {
|
||||
format!("provided method {} in {}{}",
|
||||
token::get_ident(m.pe_ident()),
|
||||
map.path_to_string(id),
|
||||
id_str)
|
||||
}
|
||||
TypeTraitItem(ref t) => {
|
||||
format!("assoc type {} in {}{}",
|
||||
token::get_ident(t.ty_param.ident),
|
||||
map.path_to_string(id),
|
||||
id_str)
|
||||
}
|
||||
}
|
||||
Some(NodeTraitItem(ti)) => {
|
||||
let kind = match ti.node {
|
||||
RequiredMethod(_) => "required method",
|
||||
ProvidedMethod(_) => "provided method",
|
||||
TypeTraitItem(..) => "assoc type",
|
||||
};
|
||||
|
||||
format!("{} {} in {}{}",
|
||||
kind,
|
||||
token::get_ident(ti.ident),
|
||||
map.path_to_string(id),
|
||||
id_str)
|
||||
}
|
||||
Some(NodeVariant(ref variant)) => {
|
||||
format!("variant {} in {}{}",
|
||||
|
@ -457,10 +457,12 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
||||
self.operation.visit_id(node_id);
|
||||
|
||||
match function_kind {
|
||||
visit::FkItemFn(_, generics, _, _) |
|
||||
visit::FkMethod(_, generics, _) => {
|
||||
visit::FkItemFn(_, generics, _, _) => {
|
||||
self.visit_generics_helper(generics)
|
||||
}
|
||||
visit::FkMethod(_, m) => {
|
||||
self.visit_generics_helper(m.pe_generics())
|
||||
}
|
||||
visit::FkFnBlock => {}
|
||||
}
|
||||
|
||||
@ -496,13 +498,14 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
||||
visit::walk_struct_def(self, struct_def);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
|
||||
match *tm {
|
||||
ast::RequiredMethod(ref m) => self.operation.visit_id(m.id),
|
||||
ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id),
|
||||
ast::TypeTraitItem(ref typ) => self.operation.visit_id(typ.ty_param.id),
|
||||
}
|
||||
visit::walk_trait_item(self, tm);
|
||||
fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
|
||||
self.operation.visit_id(ti.id);
|
||||
visit::walk_trait_item(self, ti);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
|
||||
self.operation.visit_id(ii.id);
|
||||
visit::walk_impl_item(self, ii);
|
||||
}
|
||||
|
||||
fn visit_lifetime_ref(&mut self, lifetime: &Lifetime) {
|
||||
@ -650,20 +653,18 @@ pub fn lit_is_str(lit: &Lit) -> bool {
|
||||
/// not a macro invocation. This check is guaranteed to succeed, assuming
|
||||
/// that the invocations are indeed gone.
|
||||
pub trait PostExpansionMethod {
|
||||
fn pe_ident(&self) -> ast::Ident;
|
||||
fn pe_generics<'a>(&'a self) -> &'a ast::Generics;
|
||||
fn pe_abi(&self) -> Abi;
|
||||
fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf;
|
||||
fn pe_unsafety(&self) -> ast::Unsafety;
|
||||
fn pe_fn_decl<'a>(&'a self) -> &'a ast::FnDecl;
|
||||
fn pe_body<'a>(&'a self) -> &'a ast::Block;
|
||||
fn pe_vis(&self) -> ast::Visibility;
|
||||
}
|
||||
|
||||
macro_rules! mf_method{
|
||||
($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:expr) => {
|
||||
fn $meth_name<'a>(&'a self) -> $field_ty {
|
||||
match self.node {
|
||||
match *self {
|
||||
$field_pat => $result,
|
||||
MethMac(_) => {
|
||||
panic!("expected an AST without macro invocations");
|
||||
@ -675,20 +676,18 @@ macro_rules! mf_method{
|
||||
|
||||
|
||||
impl PostExpansionMethod for Method {
|
||||
mf_method! { pe_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_,_),ident }
|
||||
mf_method! {
|
||||
pe_generics,&'a ast::Generics,
|
||||
MethDecl(_,ref generics,_,_,_,_,_,_),generics
|
||||
MethDecl(ref generics,_,_,_,_,_),generics
|
||||
}
|
||||
mf_method! { pe_abi,Abi,MethDecl(_,_,abi,_,_,_,_,_),abi }
|
||||
mf_method! { pe_abi,Abi,MethDecl(_,abi,_,_,_,_),abi }
|
||||
mf_method! {
|
||||
pe_explicit_self,&'a ast::ExplicitSelf,
|
||||
MethDecl(_,_,_,ref explicit_self,_,_,_,_),explicit_self
|
||||
MethDecl(_,_,ref explicit_self,_,_,_),explicit_self
|
||||
}
|
||||
mf_method! { pe_unsafety,ast::Unsafety,MethDecl(_,_,_,_,unsafety,_,_,_),unsafety }
|
||||
mf_method! { pe_fn_decl,&'a ast::FnDecl,MethDecl(_,_,_,_,_,ref decl,_,_),&**decl }
|
||||
mf_method! { pe_body,&'a ast::Block,MethDecl(_,_,_,_,_,_,ref body,_),&**body }
|
||||
mf_method! { pe_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,_,vis),vis }
|
||||
mf_method! { pe_unsafety,ast::Unsafety,MethDecl(_,_,_,unsafety,_,_),unsafety }
|
||||
mf_method! { pe_fn_decl,&'a ast::FnDecl,MethDecl(_,_,_,_,ref decl,_),&**decl }
|
||||
mf_method! { pe_body,&'a ast::Block,MethDecl(_,_,_,_,_,ref body),&**body }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -118,13 +118,13 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
|
||||
let item = match item {
|
||||
ast::ItemImpl(u, o, a, b, c, impl_items) => {
|
||||
let impl_items = impl_items.into_iter()
|
||||
.filter(|ii| impl_item_in_cfg(cx, ii))
|
||||
.filter(|ii| (cx.in_cfg)(&ii.attrs))
|
||||
.collect();
|
||||
ast::ItemImpl(u, o, a, b, c, impl_items)
|
||||
}
|
||||
ast::ItemTrait(u, a, b, methods) => {
|
||||
let methods = methods.into_iter()
|
||||
.filter(|m| trait_method_in_cfg(cx, m))
|
||||
.filter(|ti| (cx.in_cfg)(&ti.attrs))
|
||||
.collect();
|
||||
ast::ItemTrait(u, a, b, methods)
|
||||
}
|
||||
@ -246,25 +246,6 @@ fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool
|
||||
return (cx.in_cfg)(&item.attrs);
|
||||
}
|
||||
|
||||
fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where
|
||||
F: FnMut(&[ast::Attribute]) -> bool
|
||||
{
|
||||
match *meth {
|
||||
ast::RequiredMethod(ref meth) => (cx.in_cfg)(&meth.attrs),
|
||||
ast::ProvidedMethod(ref meth) => (cx.in_cfg)(&meth.attrs),
|
||||
ast::TypeTraitItem(ref typ) => (cx.in_cfg)(&typ.attrs),
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_item_in_cfg<F>(cx: &mut Context<F>, impl_item: &ast::ImplItem) -> bool where
|
||||
F: FnMut(&[ast::Attribute]) -> bool
|
||||
{
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(ref meth) => (cx.in_cfg)(&meth.attrs),
|
||||
ast::TypeImplItem(ref typ) => (cx.in_cfg)(&typ.attrs),
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if an item should be translated in the current crate
|
||||
// configuration based on the item's attributes
|
||||
fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attribute]) -> bool {
|
||||
|
@ -77,23 +77,16 @@ impl<F> ItemModifier for F
|
||||
#[derive(Debug,Clone)]
|
||||
pub enum Annotatable {
|
||||
Item(P<ast::Item>),
|
||||
TraitItem(ast::TraitItem),
|
||||
ImplItem(ast::ImplItem),
|
||||
TraitItem(P<ast::TraitItem>),
|
||||
ImplItem(P<ast::ImplItem>),
|
||||
}
|
||||
|
||||
impl Annotatable {
|
||||
pub fn attrs(&self) -> &[ast::Attribute] {
|
||||
match *self {
|
||||
Annotatable::Item(ref i) => &i.attrs,
|
||||
Annotatable::TraitItem(ref i) => match *i {
|
||||
ast::RequiredMethod(ref tm) => &tm.attrs,
|
||||
ast::ProvidedMethod(ref m) => &m.attrs,
|
||||
ast::TypeTraitItem(ref at) => &at.attrs,
|
||||
},
|
||||
Annotatable::ImplItem(ref i) => match *i {
|
||||
ast::MethodImplItem(ref m) => &m.attrs,
|
||||
ast::TypeImplItem(ref t) => &t.attrs,
|
||||
}
|
||||
Annotatable::TraitItem(ref ti) => &ti.attrs,
|
||||
Annotatable::ImplItem(ref ii) => &ii.attrs,
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,20 +96,12 @@ impl Annotatable {
|
||||
attrs: attrs,
|
||||
..i
|
||||
})),
|
||||
Annotatable::TraitItem(i) => Annotatable::TraitItem(match i {
|
||||
ast::RequiredMethod(tm) =>
|
||||
ast::RequiredMethod(ast::TypeMethod { attrs: attrs, ..tm }),
|
||||
ast::ProvidedMethod(m) =>
|
||||
ast::ProvidedMethod(ast::Method { attrs: attrs, ..m }),
|
||||
ast::TypeTraitItem(at) =>
|
||||
ast::TypeTraitItem(ast::AssociatedType { attrs: attrs, ..at }),
|
||||
}),
|
||||
Annotatable::ImplItem(i) => Annotatable::ImplItem(match i {
|
||||
ast::MethodImplItem(m) =>
|
||||
ast::MethodImplItem(ast::Method { attrs: attrs, ..m }),
|
||||
ast::TypeImplItem(t) =>
|
||||
ast::TypeImplItem(ast::Typedef { attrs: attrs, ..t }),
|
||||
})
|
||||
Annotatable::TraitItem(i) => Annotatable::TraitItem(i.map(|ti| {
|
||||
ast::TraitItem { attrs: attrs, ..ti }
|
||||
})),
|
||||
Annotatable::ImplItem(i) => Annotatable::ImplItem(i.map(|ii| {
|
||||
ast::ImplItem { attrs: attrs, ..ii }
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,14 +112,14 @@ impl Annotatable {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_trait_item(self) -> ast::TraitItem {
|
||||
pub fn expect_trait_item(self) -> P<ast::TraitItem> {
|
||||
match self {
|
||||
Annotatable::TraitItem(i) => i,
|
||||
_ => panic!("expected Item")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_impl_item(self) -> ast::ImplItem {
|
||||
pub fn expect_impl_item(self) -> P<ast::ImplItem> {
|
||||
match self {
|
||||
Annotatable::ImplItem(i) => i,
|
||||
_ => panic!("expected Item")
|
||||
@ -244,7 +229,7 @@ pub trait MacResult {
|
||||
}
|
||||
|
||||
/// Create zero or more methods.
|
||||
fn make_methods(self: Box<Self>) -> Option<SmallVector<ast::Method>> {
|
||||
fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
|
||||
None
|
||||
}
|
||||
|
||||
@ -290,7 +275,7 @@ make_MacEager! {
|
||||
expr: P<ast::Expr>,
|
||||
pat: P<ast::Pat>,
|
||||
items: SmallVector<P<ast::Item>>,
|
||||
methods: SmallVector<ast::Method>,
|
||||
methods: SmallVector<P<ast::ImplItem>>,
|
||||
stmt: P<ast::Stmt>,
|
||||
}
|
||||
|
||||
@ -303,7 +288,7 @@ impl MacResult for MacEager {
|
||||
self.items
|
||||
}
|
||||
|
||||
fn make_methods(self: Box<Self>) -> Option<SmallVector<ast::Method>> {
|
||||
fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
|
||||
self.methods
|
||||
}
|
||||
|
||||
@ -392,7 +377,7 @@ impl MacResult for DummyResult {
|
||||
Some(SmallVector::zero())
|
||||
}
|
||||
}
|
||||
fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<ast::Method>> {
|
||||
fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> {
|
||||
if self.expr_only {
|
||||
None
|
||||
} else {
|
||||
@ -500,9 +485,6 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
|
||||
syntax_expanders.insert(intern("quote_ty"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_ty));
|
||||
syntax_expanders.insert(intern("quote_method"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_method));
|
||||
syntax_expanders.insert(intern("quote_item"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_item));
|
||||
|
@ -386,23 +386,23 @@ impl<'a> TraitDef<'a> {
|
||||
cx: &mut ExtCtxt,
|
||||
type_ident: Ident,
|
||||
generics: &Generics,
|
||||
methods: Vec<ast::Method>) -> P<ast::Item> {
|
||||
methods: Vec<P<ast::ImplItem>>) -> P<ast::Item> {
|
||||
let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
|
||||
|
||||
// Transform associated types from `deriving::ty::Ty` into `ast::Typedef`
|
||||
// Transform associated types from `deriving::ty::Ty` into `ast::ImplItem`
|
||||
let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| {
|
||||
ast::Typedef {
|
||||
P(ast::ImplItem {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: self.span,
|
||||
ident: ident,
|
||||
vis: ast::Inherited,
|
||||
attrs: Vec::new(),
|
||||
typ: type_def.to_ty(cx,
|
||||
node: ast::TypeImplItem(type_def.to_ty(cx,
|
||||
self.span,
|
||||
type_ident,
|
||||
generics
|
||||
),
|
||||
}
|
||||
)),
|
||||
})
|
||||
});
|
||||
|
||||
let Generics { mut lifetimes, ty_params, mut where_clause } =
|
||||
@ -510,14 +510,7 @@ impl<'a> TraitDef<'a> {
|
||||
trait_generics,
|
||||
opt_trait_ref,
|
||||
self_type,
|
||||
methods.into_iter()
|
||||
.map(|method| {
|
||||
ast::MethodImplItem(method)
|
||||
}).chain(
|
||||
associated_types.map(|type_| {
|
||||
ast::TypeImplItem(type_)
|
||||
})
|
||||
).map(P).collect()))
|
||||
methods.into_iter().chain(associated_types).collect()))
|
||||
}
|
||||
|
||||
fn expand_struct_def(&self,
|
||||
@ -702,7 +695,7 @@ impl<'a> MethodDef<'a> {
|
||||
abi: Abi,
|
||||
explicit_self: ast::ExplicitSelf,
|
||||
arg_types: Vec<(Ident, P<ast::Ty>)> ,
|
||||
body: P<Expr>) -> ast::Method {
|
||||
body: P<Expr>) -> P<ast::ImplItem> {
|
||||
// create the generics that aren't for Self
|
||||
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
|
||||
|
||||
@ -725,19 +718,20 @@ impl<'a> MethodDef<'a> {
|
||||
let body_block = cx.block_expr(body);
|
||||
|
||||
// Create the method.
|
||||
ast::Method {
|
||||
attrs: self.attributes.clone(),
|
||||
P(ast::ImplItem {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
attrs: self.attributes.clone(),
|
||||
span: trait_.span,
|
||||
node: ast::MethDecl(method_ident,
|
||||
fn_generics,
|
||||
abi,
|
||||
explicit_self,
|
||||
ast::Unsafety::Normal,
|
||||
fn_decl,
|
||||
body_block,
|
||||
ast::Inherited)
|
||||
}
|
||||
vis: ast::Inherited,
|
||||
ident: method_ident,
|
||||
node: ast::MethodImplItem(
|
||||
ast::MethDecl(fn_generics,
|
||||
abi,
|
||||
explicit_self,
|
||||
ast::Unsafety::Normal,
|
||||
fn_decl,
|
||||
body_block))
|
||||
})
|
||||
}
|
||||
|
||||
/// ```
|
||||
|
@ -25,6 +25,7 @@ use ext::base::*;
|
||||
use feature_gate::{self, Features};
|
||||
use fold;
|
||||
use fold::*;
|
||||
use owned_slice::OwnedSlice;
|
||||
use parse;
|
||||
use parse::token::{fresh_mark, fresh_name, intern};
|
||||
use parse::token;
|
||||
@ -1174,29 +1175,42 @@ fn expand_annotatable(a: Annotatable,
|
||||
noop_fold_item(it, fld).into_iter().map(|i| Annotatable::Item(i)).collect()
|
||||
}
|
||||
},
|
||||
Annotatable::TraitItem(it) => match it {
|
||||
ast::TraitItem::ProvidedMethod(m) => {
|
||||
expand_method(m, fld).into_iter().map(|m|
|
||||
Annotatable::TraitItem(ast::TraitItem::ProvidedMethod(m))).collect()
|
||||
Annotatable::TraitItem(it) => match it.node {
|
||||
ast::ProvidedMethod(ast::MethMac(_)) => {
|
||||
// HACK(eddyb): Expand method macros in a trait as if they were in an impl.
|
||||
let ii = it.and_then(|ti| match ti.node {
|
||||
ast::ProvidedMethod(m) => P(ast::ImplItem {
|
||||
id: ti.id,
|
||||
ident: ti.ident,
|
||||
attrs: ti.attrs,
|
||||
vis: ast::Inherited,
|
||||
node: ast::MethodImplItem(m),
|
||||
span: ti.span
|
||||
}),
|
||||
_ => unreachable!()
|
||||
});
|
||||
expand_method(ii, fld).into_iter().map(|ii| {
|
||||
Annotatable::TraitItem(ii.and_then(|ii| P(ast::TraitItem {
|
||||
id: ii.id,
|
||||
ident: ii.ident,
|
||||
attrs: ii.attrs,
|
||||
node: match ii.node {
|
||||
ast::MethodImplItem(m) => ast::ProvidedMethod(m),
|
||||
ast::TypeImplItem(ty) => {
|
||||
ast::TypeTraitItem(OwnedSlice::empty(), Some(ty))
|
||||
}
|
||||
},
|
||||
span: ii.span
|
||||
})))
|
||||
}).collect()
|
||||
}
|
||||
ast::TraitItem::RequiredMethod(m) => {
|
||||
SmallVector::one(Annotatable::TraitItem(
|
||||
ast::TraitItem::RequiredMethod(fld.fold_type_method(m))))
|
||||
}
|
||||
ast::TraitItem::TypeTraitItem(t) => {
|
||||
SmallVector::one(Annotatable::TraitItem(
|
||||
ast::TraitItem::TypeTraitItem(fld.fold_associated_type(t))))
|
||||
_ => {
|
||||
fold::noop_fold_trait_item(it, fld).into_iter()
|
||||
.map(|ti| Annotatable::TraitItem(ti)).collect()
|
||||
}
|
||||
},
|
||||
Annotatable::ImplItem(it) => match it {
|
||||
ast::ImplItem::MethodImplItem(m) => {
|
||||
expand_method(m, fld).into_iter().map(|m|
|
||||
Annotatable::ImplItem(ast::ImplItem::MethodImplItem(m))).collect()
|
||||
}
|
||||
ast::ImplItem::TypeImplItem(t) => {
|
||||
SmallVector::one(Annotatable::ImplItem(
|
||||
ast::ImplItem::TypeImplItem(fld.fold_typedef(t))))
|
||||
}
|
||||
Annotatable::ImplItem(ii) => {
|
||||
expand_method(ii, fld).into_iter().map(Annotatable::ImplItem).collect()
|
||||
}
|
||||
};
|
||||
|
||||
@ -1204,21 +1218,6 @@ fn expand_annotatable(a: Annotatable,
|
||||
new_items
|
||||
}
|
||||
|
||||
fn expand_trait_item(i: ast::TraitItem,
|
||||
fld: &mut MacroExpander)
|
||||
-> SmallVector<ast::TraitItem> {
|
||||
expand_annotatable(Annotatable::TraitItem(i), fld)
|
||||
.into_iter().map(|i| i.expect_trait_item()).collect()
|
||||
|
||||
}
|
||||
|
||||
fn expand_impl_item(i: ast::ImplItem,
|
||||
fld: &mut MacroExpander)
|
||||
-> SmallVector<ast::ImplItem> {
|
||||
expand_annotatable(Annotatable::ImplItem(i), fld)
|
||||
.into_iter().map(|i| i.expect_impl_item()).collect()
|
||||
}
|
||||
|
||||
// partition the attributes into ItemModifiers and others
|
||||
fn modifiers(attrs: &Vec<ast::Attribute>,
|
||||
fld: &MacroExpander)
|
||||
@ -1292,37 +1291,18 @@ fn expand_item_multi_modifier(mut it: Annotatable,
|
||||
expand_item_multi_modifier(it, fld)
|
||||
}
|
||||
|
||||
// expand a method
|
||||
fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector<ast::Method> {
|
||||
match m.node {
|
||||
ast::MethDecl(ident,
|
||||
generics,
|
||||
abi,
|
||||
explicit_self,
|
||||
fn_style,
|
||||
decl,
|
||||
body,
|
||||
vis) => {
|
||||
let id = fld.new_id(m.id);
|
||||
let (rewritten_fn_decl, rewritten_body)
|
||||
= expand_and_rename_fn_decl_and_block(decl, body, fld);
|
||||
SmallVector::one(ast::Method {
|
||||
attrs: fold::fold_attrs(m.attrs, fld),
|
||||
id: id,
|
||||
span: fld.new_span(m.span),
|
||||
node: ast::MethDecl(fld.fold_ident(ident),
|
||||
noop_fold_generics(generics, fld),
|
||||
abi,
|
||||
fld.fold_explicit_self(explicit_self),
|
||||
fn_style,
|
||||
rewritten_fn_decl,
|
||||
rewritten_body,
|
||||
vis)
|
||||
})
|
||||
},
|
||||
ast::MethMac(mac) => {
|
||||
// expand an impl item if it's a method macro
|
||||
fn expand_method(ii: P<ast::ImplItem>, fld: &mut MacroExpander)
|
||||
-> SmallVector<P<ast::ImplItem>> {
|
||||
let ii = fold::noop_fold_impl_item(ii, fld).expect_one("expected one impl item");
|
||||
match ii.node {
|
||||
ast::MethodImplItem(ast::MethMac(_)) => {
|
||||
let (span, mac) = ii.and_then(|ii| match ii.node {
|
||||
ast::MethodImplItem(ast::MethMac(mac)) => (ii.span, mac),
|
||||
_ => unreachable!()
|
||||
});
|
||||
let maybe_new_methods =
|
||||
expand_mac_invoc(mac, m.span,
|
||||
expand_mac_invoc(mac, span,
|
||||
|r| r.make_methods(),
|
||||
|meths, mark| meths.move_map(|m| mark_method(m, mark)),
|
||||
fld);
|
||||
@ -1331,7 +1311,7 @@ fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector<ast::Me
|
||||
Some(methods) => {
|
||||
// expand again if necessary
|
||||
let new_methods = methods.into_iter()
|
||||
.flat_map(|m| fld.fold_method(m).into_iter())
|
||||
.flat_map(|m| expand_method(m, fld).into_iter())
|
||||
.collect();
|
||||
fld.cx.bt_pop();
|
||||
new_methods
|
||||
@ -1339,6 +1319,7 @@ fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector<ast::Me
|
||||
None => SmallVector::zero()
|
||||
}
|
||||
}
|
||||
_ => SmallVector::one(ii)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1410,16 +1391,30 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
|
||||
expand_arm(arm, self)
|
||||
}
|
||||
|
||||
fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector<ast::TraitItem> {
|
||||
expand_trait_item(i, self)
|
||||
fn fold_method(&mut self, m: ast::Method) -> ast::Method {
|
||||
match m {
|
||||
ast::MethDecl(generics, abi, explicit_self, fn_style, decl, body) => {
|
||||
let (rewritten_fn_decl, rewritten_body)
|
||||
= expand_and_rename_fn_decl_and_block(decl, body, self);
|
||||
ast::MethDecl(self.fold_generics(generics),
|
||||
abi,
|
||||
self.fold_explicit_self(explicit_self),
|
||||
fn_style,
|
||||
rewritten_fn_decl,
|
||||
rewritten_body)
|
||||
}
|
||||
ast::MethMac(mac) => ast::MethMac(mac)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVector<ast::ImplItem> {
|
||||
expand_impl_item(i, self)
|
||||
fn fold_trait_item(&mut self, i: P<ast::TraitItem>) -> SmallVector<P<ast::TraitItem>> {
|
||||
expand_annotatable(Annotatable::TraitItem(i), self)
|
||||
.into_iter().map(|i| i.expect_trait_item()).collect()
|
||||
}
|
||||
|
||||
fn fold_method(&mut self, method: ast::Method) -> SmallVector<ast::Method> {
|
||||
expand_method(method, self)
|
||||
fn fold_impl_item(&mut self, i: P<ast::ImplItem>) -> SmallVector<P<ast::ImplItem>> {
|
||||
expand_annotatable(Annotatable::ImplItem(i), self)
|
||||
.into_iter().map(|i| i.expect_impl_item()).collect()
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: P<ast::Ty>) -> P<ast::Ty> {
|
||||
@ -1565,9 +1560,9 @@ fn mark_item(expr: P<ast::Item>, m: Mrk) -> P<ast::Item> {
|
||||
}
|
||||
|
||||
// apply a given mark to the given item. Used following the expansion of a macro.
|
||||
fn mark_method(expr: ast::Method, m: Mrk) -> ast::Method {
|
||||
Marker{mark:m}.fold_method(expr)
|
||||
.expect_one("marking an item didn't return exactly one method")
|
||||
fn mark_method(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> {
|
||||
Marker{mark:m}.fold_impl_item(ii)
|
||||
.expect_one("marking an impl item didn't return exactly one method")
|
||||
}
|
||||
|
||||
/// Check that there are no macro invocations left in the AST:
|
||||
|
@ -176,7 +176,6 @@ pub mod rt {
|
||||
impl_to_source! { ast::Arg, arg_to_string }
|
||||
impl_to_source! { Generics, generics_to_string }
|
||||
impl_to_source! { P<ast::Item>, item_to_string }
|
||||
impl_to_source! { P<ast::Method>, method_to_string }
|
||||
impl_to_source! { P<ast::Stmt>, stmt_to_string }
|
||||
impl_to_source! { P<ast::Expr>, expr_to_string }
|
||||
impl_to_source! { P<ast::Pat>, pat_to_string }
|
||||
@ -311,7 +310,6 @@ pub mod rt {
|
||||
impl_to_tokens! { P<ast::Item> }
|
||||
impl_to_tokens! { P<ast::Pat> }
|
||||
impl_to_tokens! { ast::Arm }
|
||||
impl_to_tokens! { P<ast::Method> }
|
||||
impl_to_tokens_lifetime! { &'a [P<ast::Item>] }
|
||||
impl_to_tokens! { ast::Ty }
|
||||
impl_to_tokens_lifetime! { &'a [ast::Ty] }
|
||||
@ -446,15 +444,6 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt,
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
|
||||
pub fn expand_quote_method(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[ast::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_method_with_outer_attributes",
|
||||
vec!(), tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
|
||||
pub fn expand_quote_stmt(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[ast::TokenTree])
|
||||
|
@ -82,7 +82,8 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
fn make_methods(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<ast::Method>> {
|
||||
fn make_methods(self: Box<ParserAnyMacro<'a>>)
|
||||
-> Option<SmallVector<P<ast::ImplItem>>> {
|
||||
let mut ret = SmallVector::zero();
|
||||
loop {
|
||||
let mut parser = self.parser.borrow_mut();
|
||||
|
@ -110,11 +110,7 @@ pub trait Folder : Sized {
|
||||
noop_fold_fn_decl(d, self)
|
||||
}
|
||||
|
||||
fn fold_type_method(&mut self, m: TypeMethod) -> TypeMethod {
|
||||
noop_fold_type_method(m, self)
|
||||
}
|
||||
|
||||
fn fold_method(&mut self, m: Method) -> SmallVector<Method> {
|
||||
fn fold_method(&mut self, m: Method) -> Method {
|
||||
noop_fold_method(m, self)
|
||||
}
|
||||
|
||||
@ -315,15 +311,6 @@ pub trait Folder : Sized {
|
||||
noop_fold_where_predicate(where_predicate, self)
|
||||
}
|
||||
|
||||
fn fold_typedef(&mut self, typedef: Typedef) -> Typedef {
|
||||
noop_fold_typedef(typedef, self)
|
||||
}
|
||||
|
||||
fn fold_associated_type(&mut self, associated_type: AssociatedType)
|
||||
-> AssociatedType {
|
||||
noop_fold_associated_type(associated_type, self)
|
||||
}
|
||||
|
||||
fn new_id(&mut self, i: NodeId) -> NodeId {
|
||||
i
|
||||
}
|
||||
@ -829,41 +816,6 @@ pub fn noop_fold_where_predicate<T: Folder>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_typedef<T>(t: Typedef, folder: &mut T)
|
||||
-> Typedef
|
||||
where T: Folder {
|
||||
let new_id = folder.new_id(t.id);
|
||||
let new_span = folder.new_span(t.span);
|
||||
let new_attrs = t.attrs.iter().flat_map(|attr| {
|
||||
folder.fold_attribute((*attr).clone()).into_iter()
|
||||
}).collect();
|
||||
let new_ident = folder.fold_ident(t.ident);
|
||||
let new_type = folder.fold_ty(t.typ);
|
||||
ast::Typedef {
|
||||
ident: new_ident,
|
||||
typ: new_type,
|
||||
id: new_id,
|
||||
span: new_span,
|
||||
vis: t.vis,
|
||||
attrs: new_attrs,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T)
|
||||
-> AssociatedType
|
||||
where T: Folder
|
||||
{
|
||||
let new_attrs = at.attrs
|
||||
.iter()
|
||||
.flat_map(|attr| folder.fold_attribute((*attr).clone()).into_iter())
|
||||
.collect();
|
||||
let new_param = folder.fold_ty_param(at.ty_param);
|
||||
ast::AssociatedType {
|
||||
attrs: new_attrs,
|
||||
ty_param: new_param,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_struct_def<T: Folder>(struct_def: P<StructDef>, fld: &mut T) -> P<StructDef> {
|
||||
struct_def.map(|StructDef { fields, ctor_id }| StructDef {
|
||||
fields: fields.move_map(|f| fld.fold_struct_field(f)),
|
||||
@ -1020,55 +972,43 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
|
||||
|
||||
pub fn noop_fold_trait_item<T: Folder>(i: P<TraitItem>, folder: &mut T)
|
||||
-> SmallVector<P<TraitItem>> {
|
||||
i.map(|i| SmallVector::one(P(match i {
|
||||
RequiredMethod(m) => RequiredMethod(folder.fold_type_method(m)),
|
||||
ProvidedMethod(method) => {
|
||||
return folder.fold_method(method).into_iter()
|
||||
.map(|m| P(ProvidedMethod(m))).collect();
|
||||
}
|
||||
TypeTraitItem(at) => {
|
||||
TypeTraitItem(folder.fold_associated_type(at))
|
||||
}
|
||||
})))
|
||||
SmallVector::one(i.map(|TraitItem {id, ident, attrs, node, span}| TraitItem {
|
||||
id: folder.new_id(id),
|
||||
ident: folder.fold_ident(ident),
|
||||
attrs: fold_attrs(attrs, folder),
|
||||
node: match node {
|
||||
RequiredMethod(TypeMethod { unsafety, abi, decl, generics, explicit_self }) => {
|
||||
RequiredMethod(TypeMethod {
|
||||
unsafety: unsafety,
|
||||
abi: abi,
|
||||
decl: folder.fold_fn_decl(decl),
|
||||
generics: folder.fold_generics(generics),
|
||||
explicit_self: folder.fold_explicit_self(explicit_self)
|
||||
})
|
||||
}
|
||||
ProvidedMethod(m) => ProvidedMethod(folder.fold_method(m)),
|
||||
TypeTraitItem(bounds, default) => {
|
||||
TypeTraitItem(folder.fold_bounds(bounds),
|
||||
default.map(|x| folder.fold_ty(x)))
|
||||
}
|
||||
},
|
||||
span: folder.new_span(span)
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn noop_fold_impl_item<T: Folder>(i: P<ImplItem>, folder: &mut T)
|
||||
-> SmallVector<P<ImplItem>> {
|
||||
i.and_then(|i| match i {
|
||||
MethodImplItem(x) => {
|
||||
folder.fold_method(x).into_iter().map(|m| P(MethodImplItem(m))).collect()
|
||||
}
|
||||
TypeImplItem(t) => {
|
||||
SmallVector::one(TypeImplItem(folder.fold_typedef(t)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMethod {
|
||||
let TypeMethod {
|
||||
id,
|
||||
ident,
|
||||
attrs,
|
||||
unsafety,
|
||||
abi,
|
||||
decl,
|
||||
generics,
|
||||
explicit_self,
|
||||
vis,
|
||||
span
|
||||
} = m;
|
||||
TypeMethod {
|
||||
id: fld.new_id(id),
|
||||
ident: fld.fold_ident(ident),
|
||||
attrs: fold_attrs(attrs, fld),
|
||||
unsafety: unsafety,
|
||||
abi: abi,
|
||||
decl: fld.fold_fn_decl(decl),
|
||||
generics: fld.fold_generics(generics),
|
||||
explicit_self: fld.fold_explicit_self(explicit_self),
|
||||
SmallVector::one(i.map(|ImplItem {id, ident, attrs, node, vis, span}| ImplItem {
|
||||
id: folder.new_id(id),
|
||||
ident: folder.fold_ident(ident),
|
||||
attrs: fold_attrs(attrs, folder),
|
||||
vis: vis,
|
||||
span: fld.new_span(span)
|
||||
}
|
||||
node: match node {
|
||||
MethodImplItem(m) => MethodImplItem(folder.fold_method(m)),
|
||||
TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty))
|
||||
},
|
||||
span: folder.new_span(span)
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod {
|
||||
@ -1168,34 +1108,23 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
|
||||
}
|
||||
|
||||
// Default fold over a method.
|
||||
// Invariant: produces exactly one method.
|
||||
pub fn noop_fold_method<T: Folder>(Method {id, attrs, node, span}: Method, folder: &mut T)
|
||||
-> SmallVector<Method> {
|
||||
SmallVector::one(Method {
|
||||
id: folder.new_id(id),
|
||||
attrs: fold_attrs(attrs, folder),
|
||||
node: match node {
|
||||
MethDecl(ident,
|
||||
generics,
|
||||
pub fn noop_fold_method<T: Folder>(method: Method, folder: &mut T) -> Method {
|
||||
match method {
|
||||
MethDecl(generics,
|
||||
abi,
|
||||
explicit_self,
|
||||
unsafety,
|
||||
decl,
|
||||
body) => {
|
||||
MethDecl(folder.fold_generics(generics),
|
||||
abi,
|
||||
explicit_self,
|
||||
folder.fold_explicit_self(explicit_self),
|
||||
unsafety,
|
||||
decl,
|
||||
body,
|
||||
vis) => {
|
||||
MethDecl(folder.fold_ident(ident),
|
||||
folder.fold_generics(generics),
|
||||
abi,
|
||||
folder.fold_explicit_self(explicit_self),
|
||||
unsafety,
|
||||
folder.fold_fn_decl(decl),
|
||||
folder.fold_block(body),
|
||||
vis)
|
||||
},
|
||||
MethMac(mac) => MethMac(folder.fold_mac(mac)),
|
||||
folder.fold_fn_decl(decl),
|
||||
folder.fold_block(body))
|
||||
},
|
||||
span: folder.new_span(span)
|
||||
})
|
||||
MethMac(mac) => MethMac(folder.fold_mac(mac))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
|
||||
|
@ -11,7 +11,7 @@
|
||||
pub use self::PathParsingMode::*;
|
||||
|
||||
use abi;
|
||||
use ast::{AssociatedType, BareFnTy};
|
||||
use ast::{BareFnTy};
|
||||
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||
use ast::{ProvidedMethod, Public, Unsafety};
|
||||
use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
|
||||
@ -38,7 +38,7 @@ use ast::{LitBool, LitChar, LitByte, LitBinary};
|
||||
use ast::{LitStr, LitInt, Local, LocalLet};
|
||||
use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces};
|
||||
use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource};
|
||||
use ast::{Method, MutTy, BiMul, Mutability};
|
||||
use ast::{MutTy, BiMul, Mutability};
|
||||
use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot};
|
||||
use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
|
||||
use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
|
||||
@ -55,7 +55,7 @@ use ast::{TyFixedLengthVec, TyBareFn};
|
||||
use ast::{TyTypeof, TyInfer, TypeMethod};
|
||||
use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr};
|
||||
use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
|
||||
use ast::{TypeImplItem, TypeTraitItem, Typedef,};
|
||||
use ast::{TypeImplItem, TypeTraitItem};
|
||||
use ast::{UnnamedField, UnsafeBlock};
|
||||
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use ast::{Visibility, WhereClause};
|
||||
@ -1275,35 +1275,37 @@ impl<'a> Parser<'a> {
|
||||
|
||||
/// Parses `type Foo;` in a trait declaration only. The `type` keyword has
|
||||
/// already been parsed.
|
||||
fn parse_associated_type(&mut self, attrs: Vec<Attribute>)
|
||||
-> AssociatedType
|
||||
{
|
||||
let ty_param = self.parse_ty_param();
|
||||
fn parse_assoc_ty_in_trait(&mut self, attrs: Vec<Attribute>)
|
||||
-> P<TraitItem> {
|
||||
let TyParam {id, ident, bounds, default, span} = self.parse_ty_param();
|
||||
self.expect(&token::Semi);
|
||||
AssociatedType {
|
||||
P(TraitItem {
|
||||
id: id,
|
||||
ident: ident,
|
||||
attrs: attrs,
|
||||
ty_param: ty_param,
|
||||
}
|
||||
node: TypeTraitItem(bounds, default),
|
||||
span: span,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses `type Foo = TYPE;` in an implementation declaration only. The
|
||||
/// `type` keyword has already been parsed.
|
||||
fn parse_typedef(&mut self, attrs: Vec<Attribute>, vis: Visibility)
|
||||
-> Typedef {
|
||||
fn parse_assoc_ty_in_impl(&mut self, attrs: Vec<Attribute>, vis: Visibility)
|
||||
-> P<ImplItem> {
|
||||
let lo = self.span.lo;
|
||||
let ident = self.parse_ident();
|
||||
self.expect(&token::Eq);
|
||||
let typ = self.parse_ty_sum();
|
||||
let hi = self.span.hi;
|
||||
self.expect(&token::Semi);
|
||||
Typedef {
|
||||
P(ImplItem {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: mk_sp(lo, hi),
|
||||
ident: ident,
|
||||
vis: vis,
|
||||
attrs: attrs,
|
||||
typ: typ,
|
||||
}
|
||||
node: TypeImplItem(typ),
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse the items in a trait declaration
|
||||
@ -1313,14 +1315,13 @@ impl<'a> Parser<'a> {
|
||||
&token::CloseDelim(token::Brace),
|
||||
seq_sep_none(),
|
||||
|p| {
|
||||
let attrs = p.parse_outer_attributes();
|
||||
let mut attrs = p.parse_outer_attributes();
|
||||
|
||||
if p.eat_keyword(keywords::Type) {
|
||||
P(TypeTraitItem(p.parse_associated_type(attrs)))
|
||||
p.parse_assoc_ty_in_trait(attrs)
|
||||
} else {
|
||||
let lo = p.span.lo;
|
||||
|
||||
let vis = p.parse_visibility();
|
||||
let style = p.parse_unsafety();
|
||||
let abi = if p.eat_keyword(keywords::Extern) {
|
||||
p.parse_opt_abi().unwrap_or(abi::C)
|
||||
@ -1342,42 +1343,29 @@ impl<'a> Parser<'a> {
|
||||
p.parse_where_clause(&mut generics);
|
||||
|
||||
let hi = p.last_span.hi;
|
||||
match p.token {
|
||||
let node = match p.token {
|
||||
token::Semi => {
|
||||
p.bump();
|
||||
debug!("parse_trait_methods(): parsing required method");
|
||||
P(RequiredMethod(TypeMethod {
|
||||
ident: ident,
|
||||
attrs: attrs,
|
||||
RequiredMethod(TypeMethod {
|
||||
unsafety: style,
|
||||
decl: d,
|
||||
generics: generics,
|
||||
abi: abi,
|
||||
explicit_self: explicit_self,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: mk_sp(lo, hi),
|
||||
vis: vis,
|
||||
}))
|
||||
})
|
||||
}
|
||||
token::OpenDelim(token::Brace) => {
|
||||
debug!("parse_trait_methods(): parsing provided method");
|
||||
let (inner_attrs, body) =
|
||||
p.parse_inner_attrs_and_block();
|
||||
let mut attrs = attrs;
|
||||
attrs.push_all(&inner_attrs[..]);
|
||||
P(ProvidedMethod(ast::Method {
|
||||
attrs: attrs,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: mk_sp(lo, hi),
|
||||
node: ast::MethDecl(ident,
|
||||
generics,
|
||||
abi,
|
||||
explicit_self,
|
||||
style,
|
||||
d,
|
||||
body,
|
||||
vis)
|
||||
}))
|
||||
ProvidedMethod(ast::MethDecl(generics,
|
||||
abi,
|
||||
explicit_self,
|
||||
style,
|
||||
d,
|
||||
body))
|
||||
}
|
||||
|
||||
_ => {
|
||||
@ -1385,7 +1373,15 @@ impl<'a> Parser<'a> {
|
||||
p.fatal(&format!("expected `;` or `{{`, found `{}`",
|
||||
token_str)[..])
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
P(TraitItem {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident: ident,
|
||||
attrs: attrs,
|
||||
node: node,
|
||||
span: mk_sp(lo, hi),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -4692,7 +4688,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Parse a method in a trait impl
|
||||
pub fn parse_method_with_outer_attributes(&mut self) -> Method {
|
||||
pub fn parse_method_with_outer_attributes(&mut self) -> P<ImplItem> {
|
||||
let attrs = self.parse_outer_attributes();
|
||||
let visa = self.parse_visibility();
|
||||
self.parse_method(attrs, visa)
|
||||
@ -4712,12 +4708,12 @@ impl<'a> Parser<'a> {
|
||||
/// Parse a method in a trait impl, starting with `attrs` attributes.
|
||||
pub fn parse_method(&mut self,
|
||||
attrs: Vec<Attribute>,
|
||||
visa: Visibility)
|
||||
-> Method {
|
||||
vis: Visibility)
|
||||
-> P<ImplItem> {
|
||||
let lo = self.span.lo;
|
||||
|
||||
// code copied from parse_macro_use_or_failure... abstraction!
|
||||
let (method_, hi, new_attrs) = {
|
||||
let (method_, hi, new_attrs, ident) = {
|
||||
if !self.token.is_any_keyword()
|
||||
&& self.look_ahead(1, |t| *t == token::Not)
|
||||
&& (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren))
|
||||
@ -4725,7 +4721,7 @@ impl<'a> Parser<'a> {
|
||||
// method macro.
|
||||
|
||||
let last_span = self.last_span;
|
||||
self.complain_if_pub_macro(visa, last_span);
|
||||
self.complain_if_pub_macro(vis, last_span);
|
||||
|
||||
let pth = self.parse_path(NoTypesAllowed);
|
||||
self.expect(&token::Not);
|
||||
@ -4742,7 +4738,8 @@ impl<'a> Parser<'a> {
|
||||
if delim != token::Brace {
|
||||
self.expect(&token::Semi)
|
||||
}
|
||||
(ast::MethMac(m), self.span.hi, attrs)
|
||||
(ast::MethMac(m), self.span.hi, attrs,
|
||||
token::special_idents::invalid)
|
||||
} else {
|
||||
let unsafety = self.parse_unsafety();
|
||||
let abi = if self.eat_keyword(keywords::Extern) {
|
||||
@ -4761,23 +4758,23 @@ impl<'a> Parser<'a> {
|
||||
let body_span = body.span;
|
||||
let mut new_attrs = attrs;
|
||||
new_attrs.push_all(&inner_attrs[..]);
|
||||
(ast::MethDecl(ident,
|
||||
generics,
|
||||
(ast::MethDecl(generics,
|
||||
abi,
|
||||
explicit_self,
|
||||
unsafety,
|
||||
decl,
|
||||
body,
|
||||
visa),
|
||||
body_span.hi, new_attrs)
|
||||
body),
|
||||
body_span.hi, new_attrs, ident)
|
||||
}
|
||||
};
|
||||
ast::Method {
|
||||
attrs: new_attrs,
|
||||
P(ImplItem {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
attrs: new_attrs,
|
||||
vis: vis,
|
||||
ident: ident,
|
||||
node: MethodImplItem(method_),
|
||||
span: mk_sp(lo, hi),
|
||||
node: method_,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse trait Foo { ... }
|
||||
@ -4820,15 +4817,11 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
let vis = self.parse_visibility();
|
||||
if self.eat_keyword(keywords::Type) {
|
||||
impl_items.push(P(TypeImplItem(self.parse_typedef(
|
||||
method_attrs,
|
||||
vis))))
|
||||
impl_items.push(if self.eat_keyword(keywords::Type) {
|
||||
self.parse_assoc_ty_in_impl(method_attrs, vis)
|
||||
} else {
|
||||
impl_items.push(P(MethodImplItem(self.parse_method(
|
||||
method_attrs,
|
||||
vis))));
|
||||
}
|
||||
self.parse_method(method_attrs, vis)
|
||||
});
|
||||
method_attrs = vec![];
|
||||
}
|
||||
(impl_items, inner_attrs)
|
||||
|
@ -359,14 +359,6 @@ pub fn generics_to_string(generics: &ast::Generics) -> String {
|
||||
$to_string(|s| s.print_generics(generics))
|
||||
}
|
||||
|
||||
pub fn ty_method_to_string(p: &ast::TypeMethod) -> String {
|
||||
$to_string(|s| s.print_ty_method(p))
|
||||
}
|
||||
|
||||
pub fn method_to_string(p: &ast::Method) -> String {
|
||||
$to_string(|s| s.print_method(p))
|
||||
}
|
||||
|
||||
pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
|
||||
$to_string(|s| s.print_fn_block_args(p))
|
||||
}
|
||||
@ -789,23 +781,24 @@ impl<'a> State<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
|
||||
-> io::Result<()>
|
||||
{
|
||||
try!(self.print_outer_attributes(&typedef.attrs));
|
||||
fn print_associated_type(&mut self,
|
||||
ident: ast::Ident,
|
||||
bounds: Option<&ast::TyParamBounds>,
|
||||
ty: Option<&ast::Ty>)
|
||||
-> io::Result<()> {
|
||||
try!(self.word_space("type"));
|
||||
try!(self.print_ty_param(&typedef.ty_param));
|
||||
try!(self.print_ident(ident));
|
||||
if let Some(bounds) = bounds {
|
||||
try!(self.print_bounds(":", bounds));
|
||||
}
|
||||
if let Some(ty) = ty {
|
||||
try!(space(&mut self.s));
|
||||
try!(self.word_space("="));
|
||||
try!(self.print_type(ty));
|
||||
}
|
||||
word(&mut self.s, ";")
|
||||
}
|
||||
|
||||
fn print_typedef(&mut self, typedef: &ast::Typedef) -> io::Result<()> {
|
||||
try!(self.word_space("type"));
|
||||
try!(self.print_ident(typedef.ident));
|
||||
try!(space(&mut self.s));
|
||||
try!(self.word_space("="));
|
||||
try!(self.print_type(&*typedef.typ));
|
||||
word(&mut self.s, ";")
|
||||
}
|
||||
|
||||
/// Pretty-print an item
|
||||
pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
|
||||
@ -976,18 +969,11 @@ impl<'a> State<'a> {
|
||||
try!(self.bopen());
|
||||
try!(self.print_inner_attributes(&item.attrs));
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
ast::MethodImplItem(ref meth) => {
|
||||
try!(self.print_method(meth));
|
||||
}
|
||||
ast::TypeImplItem(ref typ) => {
|
||||
try!(self.print_typedef(typ));
|
||||
}
|
||||
}
|
||||
try!(self.print_impl_item(impl_item));
|
||||
}
|
||||
try!(self.bclose(item.span));
|
||||
}
|
||||
ast::ItemTrait(unsafety, ref generics, ref bounds, ref methods) => {
|
||||
ast::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => {
|
||||
try!(self.head(""));
|
||||
try!(self.print_visibility(item.vis));
|
||||
try!(self.print_unsafety(unsafety));
|
||||
@ -1008,8 +994,8 @@ impl<'a> State<'a> {
|
||||
try!(self.print_where_clause(generics));
|
||||
try!(word(&mut self.s, " "));
|
||||
try!(self.bopen());
|
||||
for meth in methods {
|
||||
try!(self.print_trait_method(meth));
|
||||
for trait_item in trait_items {
|
||||
try!(self.print_trait_item(trait_item));
|
||||
}
|
||||
try!(self.bclose(item.span));
|
||||
}
|
||||
@ -1241,48 +1227,65 @@ impl<'a> State<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> io::Result<()> {
|
||||
try!(self.hardbreak_if_not_bol());
|
||||
try!(self.maybe_print_comment(m.span.lo));
|
||||
try!(self.print_outer_attributes(&m.attrs));
|
||||
pub fn print_ty_method(&mut self,
|
||||
ident: ast::Ident,
|
||||
m: &ast::TypeMethod)
|
||||
-> io::Result<()> {
|
||||
try!(self.print_ty_fn(m.abi,
|
||||
m.unsafety,
|
||||
&*m.decl,
|
||||
Some(m.ident),
|
||||
Some(ident),
|
||||
&m.generics,
|
||||
Some(&m.explicit_self.node)));
|
||||
word(&mut self.s, ";")
|
||||
}
|
||||
|
||||
pub fn print_trait_method(&mut self,
|
||||
m: &ast::TraitItem) -> io::Result<()> {
|
||||
match *m {
|
||||
ast::RequiredMethod(ref ty_m) => self.print_ty_method(ty_m),
|
||||
ast::ProvidedMethod(ref m) => self.print_method(m),
|
||||
ast::TypeTraitItem(ref t) => self.print_associated_type(t),
|
||||
pub fn print_trait_item(&mut self, ti: &ast::TraitItem)
|
||||
-> io::Result<()> {
|
||||
try!(self.hardbreak_if_not_bol());
|
||||
try!(self.maybe_print_comment(ti.span.lo));
|
||||
try!(self.print_outer_attributes(&ti.attrs));
|
||||
match ti.node {
|
||||
ast::RequiredMethod(ref ty_m) => {
|
||||
self.print_ty_method(ti.ident, ty_m)
|
||||
}
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
self.print_method(ti.ident, &ti.attrs, ast::Inherited, m)
|
||||
}
|
||||
ast::TypeTraitItem(ref bounds, ref default) => {
|
||||
self.print_associated_type(ti.ident, Some(bounds),
|
||||
default.as_ref().map(|ty| &**ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
|
||||
match *ii {
|
||||
ast::MethodImplItem(ref m) => self.print_method(m),
|
||||
ast::TypeImplItem(ref td) => self.print_typedef(td),
|
||||
try!(self.hardbreak_if_not_bol());
|
||||
try!(self.maybe_print_comment(ii.span.lo));
|
||||
try!(self.print_outer_attributes(&ii.attrs));
|
||||
match ii.node {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
self.print_method(ii.ident, &ii.attrs, ii.vis, m)
|
||||
}
|
||||
ast::TypeImplItem(ref ty) => {
|
||||
self.print_associated_type(ii.ident, None, Some(ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_method(&mut self, meth: &ast::Method) -> io::Result<()> {
|
||||
try!(self.hardbreak_if_not_bol());
|
||||
try!(self.maybe_print_comment(meth.span.lo));
|
||||
try!(self.print_outer_attributes(&meth.attrs));
|
||||
match meth.node {
|
||||
ast::MethDecl(ident,
|
||||
ref generics,
|
||||
pub fn print_method(&mut self,
|
||||
ident: ast::Ident,
|
||||
attrs: &[ast::Attribute],
|
||||
vis: ast::Visibility,
|
||||
meth: &ast::Method)
|
||||
-> io::Result<()> {
|
||||
match *meth {
|
||||
ast::MethDecl(ref generics,
|
||||
abi,
|
||||
ref explicit_self,
|
||||
unsafety,
|
||||
ref decl,
|
||||
ref body,
|
||||
vis) => {
|
||||
ref body) => {
|
||||
try!(self.print_fn(&**decl,
|
||||
Some(unsafety),
|
||||
abi,
|
||||
@ -1291,7 +1294,7 @@ impl<'a> State<'a> {
|
||||
Some(&explicit_self.node),
|
||||
vis));
|
||||
try!(word(&mut self.s, " "));
|
||||
self.print_block_with_attrs(&**body, &meth.attrs)
|
||||
self.print_block_with_attrs(&**body, attrs)
|
||||
},
|
||||
ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
|
||||
..}) => {
|
||||
|
@ -38,7 +38,7 @@ pub enum FnKind<'a> {
|
||||
FkItemFn(Ident, &'a Generics, Unsafety, Abi),
|
||||
|
||||
/// fn foo(&self)
|
||||
FkMethod(Ident, &'a Generics, &'a Method),
|
||||
FkMethod(Ident, &'a Method),
|
||||
|
||||
/// |x, y| ...
|
||||
/// proc(x, y) ...
|
||||
@ -77,8 +77,8 @@ pub trait Visitor<'v> : Sized {
|
||||
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) {
|
||||
walk_fn(self, fk, fd, b, s)
|
||||
}
|
||||
fn visit_ty_method(&mut self, t: &'v TypeMethod) { walk_ty_method(self, t) }
|
||||
fn visit_trait_item(&mut self, t: &'v TraitItem) { walk_trait_item(self, t) }
|
||||
fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) }
|
||||
fn visit_impl_item(&mut self, ii: &'v ImplItem) { walk_impl_item(self, ii) }
|
||||
fn visit_trait_ref(&mut self, t: &'v TraitRef) { walk_trait_ref(self, t) }
|
||||
fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
|
||||
walk_ty_param_bound(self, bounds)
|
||||
@ -143,13 +143,7 @@ pub fn walk_inlined_item<'v,V>(visitor: &mut V, item: &'v InlinedItem)
|
||||
IIItem(ref i) => visitor.visit_item(&**i),
|
||||
IIForeign(ref i) => visitor.visit_foreign_item(&**i),
|
||||
IITraitItem(_, ref ti) => visitor.visit_trait_item(ti),
|
||||
IIImplItem(_, MethodImplItem(ref m)) => {
|
||||
walk_method_helper(visitor, m)
|
||||
}
|
||||
IIImplItem(_, TypeImplItem(ref typedef)) => {
|
||||
visitor.visit_ident(typedef.span, typedef.ident);
|
||||
visitor.visit_ty(&*typedef.typ);
|
||||
}
|
||||
IIImplItem(_, ref ii) => visitor.visit_impl_item(ii),
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,8 +196,6 @@ pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
}
|
||||
}
|
||||
|
||||
/// Like with walk_method_helper this doesn't correspond to a method
|
||||
/// in Visitor, and so it gets a _helper suffix.
|
||||
pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
|
||||
trait_ref: &'v PolyTraitRef,
|
||||
_modifier: &'v TraitBoundModifier)
|
||||
@ -213,8 +205,6 @@ pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
|
||||
visitor.visit_trait_ref(&trait_ref.trait_ref);
|
||||
}
|
||||
|
||||
/// Like with walk_method_helper this doesn't correspond to a method
|
||||
/// in Visitor, and so it gets a _helper suffix.
|
||||
pub fn walk_trait_ref<'v,V>(visitor: &mut V,
|
||||
trait_ref: &'v TraitRef)
|
||||
where V: Visitor<'v>
|
||||
@ -294,15 +284,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
||||
}
|
||||
visitor.visit_ty(&**typ);
|
||||
for impl_item in impl_items {
|
||||
match **impl_item {
|
||||
MethodImplItem(ref method) => {
|
||||
walk_method_helper(visitor, method)
|
||||
}
|
||||
TypeImplItem(ref typedef) => {
|
||||
visitor.visit_ident(typedef.span, typedef.ident);
|
||||
visitor.visit_ty(&*typedef.typ);
|
||||
}
|
||||
}
|
||||
visitor.visit_impl_item(impl_item);
|
||||
}
|
||||
}
|
||||
ItemStruct(ref struct_definition, ref generics) => {
|
||||
@ -561,15 +543,11 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_ty_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v TyParam) {
|
||||
visitor.visit_ident(param.span, param.ident);
|
||||
walk_ty_param_bounds_helper(visitor, ¶m.bounds);
|
||||
walk_ty_opt(visitor, ¶m.default);
|
||||
}
|
||||
|
||||
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
|
||||
for type_parameter in &*generics.ty_params {
|
||||
walk_ty_param(visitor, type_parameter);
|
||||
for param in &*generics.ty_params {
|
||||
visitor.visit_ident(param.span, param.ident);
|
||||
walk_ty_param_bounds_helper(visitor, ¶m.bounds);
|
||||
walk_ty_opt(visitor, ¶m.default);
|
||||
}
|
||||
walk_lifetime_decls_helper(visitor, &generics.lifetimes);
|
||||
for predicate in &generics.where_clause.predicates {
|
||||
@ -618,19 +596,19 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &
|
||||
// visit_fn() and check for FkMethod(). I named this visit_method_helper()
|
||||
// because it is not a default impl of any method, though I doubt that really
|
||||
// clarifies anything. - Niko
|
||||
pub fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V, method: &'v Method) {
|
||||
match method.node {
|
||||
MethDecl(ident, ref generics, _, _, _, ref decl, ref body, _) => {
|
||||
visitor.visit_ident(method.span, ident);
|
||||
visitor.visit_fn(FkMethod(ident, generics, method),
|
||||
fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
id: NodeId,
|
||||
ident: Ident,
|
||||
span: Span,
|
||||
method: &'v Method) {
|
||||
match *method {
|
||||
MethDecl(_, _, _, _, ref decl, ref body) => {
|
||||
visitor.visit_ident(span, ident);
|
||||
visitor.visit_fn(FkMethod(ident, method),
|
||||
&**decl,
|
||||
&**body,
|
||||
method.span,
|
||||
method.id);
|
||||
for attr in &method.attrs {
|
||||
visitor.visit_attribute(attr);
|
||||
}
|
||||
|
||||
span,
|
||||
id);
|
||||
},
|
||||
MethMac(ref mac) => visitor.visit_mac(mac)
|
||||
}
|
||||
@ -647,13 +625,13 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
FkItemFn(_, generics, _, _) => {
|
||||
visitor.visit_generics(generics);
|
||||
}
|
||||
FkMethod(_, generics, method) => {
|
||||
visitor.visit_generics(generics);
|
||||
match method.node {
|
||||
MethDecl(_, _, _, ref explicit_self, _, _, _, _) =>
|
||||
visitor.visit_explicit_self(explicit_self),
|
||||
MethMac(ref mac) =>
|
||||
visitor.visit_mac(mac)
|
||||
FkMethod(_, method) => {
|
||||
match *method {
|
||||
MethDecl(ref generics, _, ref explicit_self, _, _, _) => {
|
||||
visitor.visit_generics(generics);
|
||||
visitor.visit_explicit_self(explicit_self);
|
||||
}
|
||||
MethMac(ref mac) => visitor.visit_mac(mac)
|
||||
}
|
||||
}
|
||||
FkFnBlock(..) => {}
|
||||
@ -662,25 +640,46 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
visitor.visit_block(function_body)
|
||||
}
|
||||
|
||||
pub fn walk_ty_method<'v, V: Visitor<'v>>(visitor: &mut V, method_type: &'v TypeMethod) {
|
||||
visitor.visit_ident(method_type.span, method_type.ident);
|
||||
visitor.visit_explicit_self(&method_type.explicit_self);
|
||||
for argument_type in &method_type.decl.inputs {
|
||||
visitor.visit_ty(&*argument_type.ty)
|
||||
}
|
||||
visitor.visit_generics(&method_type.generics);
|
||||
walk_fn_ret_ty(visitor, &method_type.decl.output);
|
||||
for attr in &method_type.attrs {
|
||||
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
|
||||
visitor.visit_ident(trait_item.span, trait_item.ident);
|
||||
for attr in &trait_item.attrs {
|
||||
visitor.visit_attribute(attr);
|
||||
}
|
||||
match trait_item.node {
|
||||
RequiredMethod(ref method_type) => {
|
||||
visitor.visit_explicit_self(&method_type.explicit_self);
|
||||
visitor.visit_generics(&method_type.generics);
|
||||
walk_fn_decl(visitor, &method_type.decl);
|
||||
}
|
||||
ProvidedMethod(ref method) => {
|
||||
walk_method_helper(visitor,
|
||||
trait_item.id,
|
||||
trait_item.ident,
|
||||
trait_item.span,
|
||||
method);
|
||||
}
|
||||
TypeTraitItem(ref bounds, ref default) => {
|
||||
walk_ty_param_bounds_helper(visitor, bounds);
|
||||
walk_ty_opt(visitor, default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_method: &'v TraitItem) {
|
||||
match *trait_method {
|
||||
RequiredMethod(ref method_type) => visitor.visit_ty_method(method_type),
|
||||
ProvidedMethod(ref method) => walk_method_helper(visitor, method),
|
||||
TypeTraitItem(ref associated_type) => {
|
||||
walk_ty_param(visitor, &associated_type.ty_param);
|
||||
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
|
||||
visitor.visit_ident(impl_item.span, impl_item.ident);
|
||||
for attr in &impl_item.attrs {
|
||||
visitor.visit_attribute(attr);
|
||||
}
|
||||
match impl_item.node {
|
||||
MethodImplItem(ref method) => {
|
||||
walk_method_helper(visitor,
|
||||
impl_item.id,
|
||||
impl_item.ident,
|
||||
impl_item.span,
|
||||
method);
|
||||
}
|
||||
TypeImplItem(ref ty) => {
|
||||
visitor.visit_ty(ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,16 +81,7 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
|
||||
..(*quote_item!(cx, enum Foo2 { Bar2, Baz2 }).unwrap()).clone()
|
||||
}))
|
||||
}
|
||||
Annotatable::ImplItem(it) => {
|
||||
Annotatable::ImplItem(ImplItem::MethodImplItem(
|
||||
quote_method!(cx, fn foo(&self) -> i32 { 42 })
|
||||
))
|
||||
}
|
||||
Annotatable::TraitItem(it) => {
|
||||
Annotatable::TraitItem(TraitItem::ProvidedMethod(
|
||||
quote_method!(cx, fn foo(&self) -> i32 { 0 })
|
||||
))
|
||||
}
|
||||
it => it
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,8 @@ trait B {
|
||||
}
|
||||
|
||||
pub trait C { //~ ERROR: missing documentation for a trait
|
||||
fn foo(&self); //~ ERROR: missing documentation for a type method
|
||||
fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a method
|
||||
fn foo(&self); //~ ERROR: missing documentation for a trait method
|
||||
fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a default method
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
|
@ -13,7 +13,7 @@ fn main() {
|
||||
pub struct A; //~ ERROR: visibility has no effect
|
||||
pub enum B {} //~ ERROR: visibility has no effect
|
||||
pub trait C { //~ ERROR: visibility has no effect
|
||||
pub fn foo(&self) {} //~ ERROR: visibility has no effect
|
||||
fn foo(&self) {}
|
||||
}
|
||||
impl A {
|
||||
pub fn foo(&self) {} //~ ERROR: visibility has no effect
|
||||
|
@ -12,10 +12,7 @@ struct A { pub i: isize }
|
||||
pub enum C { pub Variant } //~ ERROR: unnecessary `pub`
|
||||
|
||||
pub trait E {
|
||||
pub fn foo(&self) {} //~ ERROR: unnecessary visibility
|
||||
}
|
||||
trait F {
|
||||
pub fn foo(&self) {} //~ ERROR: unnecessary visibility
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
impl E for A {
|
||||
|
@ -9,5 +9,5 @@
|
||||
// except according to those terms.
|
||||
|
||||
trait MyTrait<T>: Iterator {
|
||||
Item = T; //~ ERROR expected one of `extern`, `fn`, `pub`, `type`, or `unsafe`, found `Item`
|
||||
Item = T; //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `Item`
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -8,11 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub trait E {
|
||||
pub fn foo(&self); //~ ERROR: unnecessary visibility
|
||||
}
|
||||
trait F {
|
||||
pub fn foo(&self); //~ ERROR: unnecessary visibility
|
||||
trait Foo {
|
||||
pub type Foo; //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `pub`
|
||||
}
|
||||
|
||||
fn main() {}
|
15
src/test/parse-fail/trait-pub-method.rs
Normal file
15
src/test/parse-fail/trait-pub-method.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
trait Foo {
|
||||
pub fn foo(); //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `pub`
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -36,9 +36,6 @@ fn syntax_extension(cx: &ExtCtxt) {
|
||||
let i: Option<P<syntax::ast::Item>> = quote_item!(cx, #[derive(Eq)] struct Foo; );
|
||||
assert!(i.is_some());
|
||||
|
||||
let _j: P<syntax::ast::Method> = quote_method!(cx, fn foo(&self) {});
|
||||
let _k: P<syntax::ast::Method> = quote_method!(cx, #[doc = "hello"] fn foo(&self) {});
|
||||
|
||||
let _l: P<syntax::ast::Ty> = quote_ty!(cx, &int);
|
||||
|
||||
let _m: Vec<syntax::ast::TokenTree> = quote_matcher!(cx, $($foo:tt,)* bar);
|
||||
|
Loading…
Reference in New Issue
Block a user