1
Fork 0

Lifting Generics from MethodSig to TraitItem and ImplItem since we want to support generics in each variant of TraitItem and ImplItem

This commit is contained in:
Sunjay Varma 2017-09-21 22:18:47 -04:00
parent f6d7514545
commit f61394f0bd
11 changed files with 51 additions and 40 deletions

View file

@ -1548,7 +1548,7 @@ impl<'a> LoweringContext<'a> {
} }
TraitItemKind::Method(ref sig, None) => { TraitItemKind::Method(ref sig, None) => {
let names = this.lower_fn_args_to_names(&sig.decl); let names = this.lower_fn_args_to_names(&sig.decl);
hir::TraitItemKind::Method(this.lower_method_sig(sig), hir::TraitItemKind::Method(this.lower_method_sig(&i.generics, sig),
hir::TraitMethod::Required(names)) hir::TraitMethod::Required(names))
} }
TraitItemKind::Method(ref sig, Some(ref body)) => { TraitItemKind::Method(ref sig, Some(ref body)) => {
@ -1556,7 +1556,7 @@ impl<'a> LoweringContext<'a> {
let body = this.lower_block(body, false); let body = this.lower_block(body, false);
this.expr_block(body, ThinVec::new()) this.expr_block(body, ThinVec::new())
}); });
hir::TraitItemKind::Method(this.lower_method_sig(sig), hir::TraitItemKind::Method(this.lower_method_sig(&i.generics, sig),
hir::TraitMethod::Provided(body_id)) hir::TraitMethod::Provided(body_id))
} }
TraitItemKind::Type(ref bounds, ref default) => { TraitItemKind::Type(ref bounds, ref default) => {
@ -1615,7 +1615,7 @@ impl<'a> LoweringContext<'a> {
let body = this.lower_block(body, false); let body = this.lower_block(body, false);
this.expr_block(body, ThinVec::new()) this.expr_block(body, ThinVec::new())
}); });
hir::ImplItemKind::Method(this.lower_method_sig(sig), body_id) hir::ImplItemKind::Method(this.lower_method_sig(&i.generics, sig), body_id)
} }
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)), ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
@ -1727,9 +1727,9 @@ impl<'a> LoweringContext<'a> {
}) })
} }
fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig { fn lower_method_sig(&mut self, generics: &Generics, sig: &MethodSig) -> hir::MethodSig {
hir::MethodSig { hir::MethodSig {
generics: self.lower_generics(&sig.generics), generics: self.lower_generics(generics),
abi: sig.abi, abi: sig.abi,
unsafety: self.lower_unsafety(sig.unsafety), unsafety: self.lower_unsafety(sig.unsafety),
constness: self.lower_constness(sig.constness), constness: self.lower_constness(sig.constness),

View file

@ -723,7 +723,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
ItemRibKind ItemRibKind
} }
FnKind::Method(_, sig, _, _) => { FnKind::Method(_, sig, _, _) => {
self.visit_generics(&sig.generics);
MethodRibKind(!sig.decl.has_self()) MethodRibKind(!sig.decl.has_self())
} }
FnKind::Closure(_) => ClosureRibKind(node_id), FnKind::Closure(_) => ClosureRibKind(node_id),
@ -1864,6 +1863,7 @@ impl<'a> Resolver<'a> {
for trait_item in trait_items { for trait_item in trait_items {
this.check_proc_macro_attrs(&trait_item.attrs); this.check_proc_macro_attrs(&trait_item.attrs);
this.visit_generics(&trait_item.generics);
match trait_item.node { match trait_item.node {
TraitItemKind::Const(ref ty, ref default) => { TraitItemKind::Const(ref ty, ref default) => {
@ -1880,7 +1880,7 @@ impl<'a> Resolver<'a> {
} }
TraitItemKind::Method(ref sig, _) => { TraitItemKind::Method(ref sig, _) => {
let type_parameters = let type_parameters =
HasTypeParameters(&sig.generics, HasTypeParameters(&trait_item.generics,
MethodRibKind(!sig.decl.has_self())); MethodRibKind(!sig.decl.has_self()));
this.with_type_parameter_rib(type_parameters, |this| { this.with_type_parameter_rib(type_parameters, |this| {
visit::walk_trait_item(this, trait_item) visit::walk_trait_item(this, trait_item)
@ -2075,6 +2075,7 @@ impl<'a> Resolver<'a> {
this.with_current_self_type(self_type, |this| { this.with_current_self_type(self_type, |this| {
for impl_item in impl_items { for impl_item in impl_items {
this.check_proc_macro_attrs(&impl_item.attrs); this.check_proc_macro_attrs(&impl_item.attrs);
this.visit_generics(&impl_item.generics);
this.resolve_visibility(&impl_item.vis); this.resolve_visibility(&impl_item.vis);
match impl_item.node { match impl_item.node {
ImplItemKind::Const(..) => { ImplItemKind::Const(..) => {
@ -2097,7 +2098,7 @@ impl<'a> Resolver<'a> {
// We also need a new scope for the method- // We also need a new scope for the method-
// specific type parameters. // specific type parameters.
let type_parameters = let type_parameters =
HasTypeParameters(&sig.generics, HasTypeParameters(&impl_item.generics,
MethodRibKind(!sig.decl.has_self())); MethodRibKind(!sig.decl.has_self()));
this.with_type_parameter_rib(type_parameters, |this| { this.with_type_parameter_rib(type_parameters, |this| {
visit::walk_impl_item(this, impl_item); visit::walk_impl_item(this, impl_item);

View file

@ -354,23 +354,24 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
body: Option<&'l ast::Block>, body: Option<&'l ast::Block>,
id: ast::NodeId, id: ast::NodeId,
name: ast::Ident, name: ast::Ident,
generics: &'l ast::Generics,
vis: ast::Visibility, vis: ast::Visibility,
span: Span) { span: Span) {
debug!("process_method: {}:{}", id, name); debug!("process_method: {}:{}", id, name);
if let Some(mut method_data) = self.save_ctxt.get_method_data(id, name.name, span) { if let Some(mut method_data) = self.save_ctxt.get_method_data(id, name.name, span) {
let sig_str = ::make_signature(&sig.decl, &sig.generics); let sig_str = ::make_signature(&sig.decl, &generics);
if body.is_some() { if body.is_some() {
self.nest_tables(id, |v| { self.nest_tables(id, |v| {
v.process_formals(&sig.decl.inputs, &method_data.qualname) v.process_formals(&sig.decl.inputs, &method_data.qualname)
}); });
} }
self.process_generic_params(&sig.generics, span, &method_data.qualname, id); self.process_generic_params(&generics, span, &method_data.qualname, id);
method_data.value = sig_str; method_data.value = sig_str;
method_data.sig = sig::method_signature(id, name, sig, &self.save_ctxt); method_data.sig = sig::method_signature(id, name, generics, sig, &self.save_ctxt);
self.dumper.dump_def(vis == ast::Visibility::Public, method_data); self.dumper.dump_def(vis == ast::Visibility::Public, method_data);
} }
@ -1007,6 +1008,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
body.as_ref().map(|x| &**x), body.as_ref().map(|x| &**x),
trait_item.id, trait_item.id,
trait_item.ident, trait_item.ident,
&trait_item.generics,
ast::Visibility::Public, ast::Visibility::Public,
trait_item.span); trait_item.span);
} }
@ -1066,6 +1068,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
Some(body), Some(body),
impl_item.id, impl_item.id,
impl_item.ident, impl_item.ident,
&impl_item.generics,
impl_item.vis.clone(), impl_item.vis.clone(),
impl_item.span); impl_item.span);
} }

View file

@ -77,13 +77,14 @@ pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext) -> Option<Si
pub fn method_signature(id: NodeId, pub fn method_signature(id: NodeId,
ident: ast::Ident, ident: ast::Ident,
generics: &ast::Generics,
m: &ast::MethodSig, m: &ast::MethodSig,
scx: &SaveContext) scx: &SaveContext)
-> Option<Signature> { -> Option<Signature> {
if !scx.config.signatures { if !scx.config.signatures {
return None; return None;
} }
make_method_signature(id, ident, m, scx).ok() make_method_signature(id, ident, generics, m, scx).ok()
} }
pub fn assoc_const_signature(id: NodeId, pub fn assoc_const_signature(id: NodeId,
@ -895,6 +896,7 @@ fn make_assoc_const_signature(id: NodeId,
fn make_method_signature(id: NodeId, fn make_method_signature(id: NodeId,
ident: ast::Ident, ident: ast::Ident,
generics: &ast::Generics,
m: &ast::MethodSig, m: &ast::MethodSig,
scx: &SaveContext) scx: &SaveContext)
-> Result { -> Result {
@ -915,7 +917,7 @@ fn make_method_signature(id: NodeId,
let mut sig = name_and_generics(text, let mut sig = name_and_generics(text,
0, 0,
&m.generics, generics,
id, id,
ident, ident,
scx)?; scx)?;

View file

@ -1178,7 +1178,6 @@ pub struct MethodSig {
pub constness: Spanned<Constness>, pub constness: Spanned<Constness>,
pub abi: Abi, pub abi: Abi,
pub decl: P<FnDecl>, pub decl: P<FnDecl>,
pub generics: Generics,
} }
/// Represents an item declaration within a trait declaration, /// Represents an item declaration within a trait declaration,
@ -1190,6 +1189,7 @@ pub struct TraitItem {
pub id: NodeId, pub id: NodeId,
pub ident: Ident, pub ident: Ident,
pub attrs: Vec<Attribute>, pub attrs: Vec<Attribute>,
pub generics: Generics,
pub node: TraitItemKind, pub node: TraitItemKind,
pub span: Span, pub span: Span,
/// See `Item::tokens` for what this is /// See `Item::tokens` for what this is
@ -1211,6 +1211,7 @@ pub struct ImplItem {
pub vis: Visibility, pub vis: Visibility,
pub defaultness: Defaultness, pub defaultness: Defaultness,
pub attrs: Vec<Attribute>, pub attrs: Vec<Attribute>,
pub generics: Generics,
pub node: ImplItemKind, pub node: ImplItemKind,
pub span: Span, pub span: Span,
/// See `Item::tokens` for what this is /// See `Item::tokens` for what this is

View file

@ -32,6 +32,7 @@ pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion {
let ident = keywords::Invalid.ident(); let ident = keywords::Invalid.ident();
let attrs = Vec::new(); let attrs = Vec::new();
let generics = ast::Generics::default();
let vis = ast::Visibility::Inherited; let vis = ast::Visibility::Inherited;
let span = DUMMY_SP; let span = DUMMY_SP;
let expr_placeholder = || P(ast::Expr { let expr_placeholder = || P(ast::Expr {
@ -49,12 +50,12 @@ pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion {
tokens: None, tokens: None,
}))), }))),
ExpansionKind::TraitItems => Expansion::TraitItems(SmallVector::one(ast::TraitItem { ExpansionKind::TraitItems => Expansion::TraitItems(SmallVector::one(ast::TraitItem {
id, span, ident, attrs, id, span, ident, attrs, generics,
node: ast::TraitItemKind::Macro(mac_placeholder()), node: ast::TraitItemKind::Macro(mac_placeholder()),
tokens: None, tokens: None,
})), })),
ExpansionKind::ImplItems => Expansion::ImplItems(SmallVector::one(ast::ImplItem { ExpansionKind::ImplItems => Expansion::ImplItems(SmallVector::one(ast::ImplItem {
id, span, ident, vis, attrs, id, span, ident, vis, attrs, generics,
node: ast::ImplItemKind::Macro(mac_placeholder()), node: ast::ImplItemKind::Macro(mac_placeholder()),
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
tokens: None, tokens: None,

View file

@ -943,6 +943,7 @@ pub fn noop_fold_trait_item<T: Folder>(i: TraitItem, folder: &mut T)
id: folder.new_id(i.id), id: folder.new_id(i.id),
ident: folder.fold_ident(i.ident), ident: folder.fold_ident(i.ident),
attrs: fold_attrs(i.attrs, folder), attrs: fold_attrs(i.attrs, folder),
generics: folder.fold_generics(i.generics),
node: match i.node { node: match i.node {
TraitItemKind::Const(ty, default) => { TraitItemKind::Const(ty, default) => {
TraitItemKind::Const(folder.fold_ty(ty), TraitItemKind::Const(folder.fold_ty(ty),
@ -972,6 +973,7 @@ pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T)
vis: folder.fold_vis(i.vis), vis: folder.fold_vis(i.vis),
ident: folder.fold_ident(i.ident), ident: folder.fold_ident(i.ident),
attrs: fold_attrs(i.attrs, folder), attrs: fold_attrs(i.attrs, folder),
generics: folder.fold_generics(i.generics),
defaultness: i.defaultness, defaultness: i.defaultness,
node: match i.node { node: match i.node {
ast::ImplItemKind::Const(ty, expr) => { ast::ImplItemKind::Const(ty, expr) => {
@ -1074,7 +1076,6 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: ForeignItem, folder: &mut T) -> For
pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig { pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig {
MethodSig { MethodSig {
generics: folder.fold_generics(sig.generics),
abi: sig.abi, abi: sig.abi,
unsafety: sig.unsafety, unsafety: sig.unsafety,
constness: sig.constness, constness: sig.constness,

View file

@ -1287,10 +1287,10 @@ impl<'a> Parser<'a> {
mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> { mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> {
let lo = self.span; let lo = self.span;
let (name, node) = if self.eat_keyword(keywords::Type) { let (name, node, generics) = if self.eat_keyword(keywords::Type) {
let TyParam {ident, bounds, default, ..} = self.parse_ty_param(vec![])?; let TyParam {ident, bounds, default, ..} = self.parse_ty_param(vec![])?;
self.expect(&token::Semi)?; self.expect(&token::Semi)?;
(ident, TraitItemKind::Type(bounds, default)) (ident, TraitItemKind::Type(bounds, default), ast::Generics::default())
} else if self.is_const_item() { } else if self.is_const_item() {
self.expect_keyword(keywords::Const)?; self.expect_keyword(keywords::Const)?;
let ident = self.parse_ident()?; let ident = self.parse_ident()?;
@ -1305,7 +1305,7 @@ impl<'a> Parser<'a> {
self.expect(&token::Semi)?; self.expect(&token::Semi)?;
None None
}; };
(ident, TraitItemKind::Const(ty, default)) (ident, TraitItemKind::Const(ty, default), ast::Generics::default())
} else if self.token.is_path_start() { } else if self.token.is_path_start() {
// trait item macro. // trait item macro.
// code copied from parse_macro_use_or_failure... abstraction! // code copied from parse_macro_use_or_failure... abstraction!
@ -1328,7 +1328,7 @@ impl<'a> Parser<'a> {
} }
let mac = respan(lo.to(self.prev_span), Mac_ { path: pth, tts: tts }); let mac = respan(lo.to(self.prev_span), Mac_ { path: pth, tts: tts });
(keywords::Invalid.ident(), ast::TraitItemKind::Macro(mac)) (keywords::Invalid.ident(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
} else { } else {
let (constness, unsafety, abi) = self.parse_fn_front_matter()?; let (constness, unsafety, abi) = self.parse_fn_front_matter()?;
@ -1341,13 +1341,12 @@ impl<'a> Parser<'a> {
// definition... // definition...
p.parse_arg_general(false) p.parse_arg_general(false)
})?; })?;
generics.where_clause = self.parse_where_clause()?; generics.where_clause = self.parse_where_clause()?;
let sig = ast::MethodSig { let sig = ast::MethodSig {
unsafety, unsafety,
constness, constness,
decl: d, decl: d,
generics,
abi, abi,
}; };
@ -1370,13 +1369,14 @@ impl<'a> Parser<'a> {
return Err(self.fatal(&format!("expected `;` or `{{`, found `{}`", token_str))); return Err(self.fatal(&format!("expected `;` or `{{`, found `{}`", token_str)));
} }
}; };
(ident, ast::TraitItemKind::Method(sig, body)) (ident, ast::TraitItemKind::Method(sig, body), generics)
}; };
Ok(TraitItem { Ok(TraitItem {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
ident: name, ident: name,
attrs, attrs,
generics,
node, node,
span: lo.to(self.prev_span), span: lo.to(self.prev_span),
tokens: None, tokens: None,
@ -4901,12 +4901,12 @@ impl<'a> Parser<'a> {
let lo = self.span; let lo = self.span;
let vis = self.parse_visibility(false)?; let vis = self.parse_visibility(false)?;
let defaultness = self.parse_defaultness()?; let defaultness = self.parse_defaultness()?;
let (name, node) = if self.eat_keyword(keywords::Type) { let (name, node, generics) = if self.eat_keyword(keywords::Type) {
let name = self.parse_ident()?; let name = self.parse_ident()?;
self.expect(&token::Eq)?; self.expect(&token::Eq)?;
let typ = self.parse_ty()?; let typ = self.parse_ty()?;
self.expect(&token::Semi)?; self.expect(&token::Semi)?;
(name, ast::ImplItemKind::Type(typ)) (name, ast::ImplItemKind::Type(typ), ast::Generics::default())
} else if self.is_const_item() { } else if self.is_const_item() {
self.expect_keyword(keywords::Const)?; self.expect_keyword(keywords::Const)?;
let name = self.parse_ident()?; let name = self.parse_ident()?;
@ -4915,11 +4915,11 @@ impl<'a> Parser<'a> {
self.expect(&token::Eq)?; self.expect(&token::Eq)?;
let expr = self.parse_expr()?; let expr = self.parse_expr()?;
self.expect(&token::Semi)?; self.expect(&token::Semi)?;
(name, ast::ImplItemKind::Const(typ, expr)) (name, ast::ImplItemKind::Const(typ, expr), ast::Generics::default())
} else { } else {
let (name, inner_attrs, node) = self.parse_impl_method(&vis, at_end)?; let (name, inner_attrs, generics, node) = self.parse_impl_method(&vis, at_end)?;
attrs.extend(inner_attrs); attrs.extend(inner_attrs);
(name, node) (name, node, generics)
}; };
Ok(ImplItem { Ok(ImplItem {
@ -4929,6 +4929,7 @@ impl<'a> Parser<'a> {
vis, vis,
defaultness, defaultness,
attrs, attrs,
generics,
node, node,
tokens: None, tokens: None,
}) })
@ -4986,7 +4987,7 @@ impl<'a> Parser<'a> {
/// Parse a method or a macro invocation in a trait impl. /// Parse a method or a macro invocation in a trait impl.
fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool) fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
-> PResult<'a, (Ident, Vec<ast::Attribute>, ast::ImplItemKind)> { -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::Generics, ast::ImplItemKind)> {
// code copied from parse_macro_use_or_failure... abstraction! // code copied from parse_macro_use_or_failure... abstraction!
if self.token.is_path_start() { if self.token.is_path_start() {
// Method macro. // Method macro.
@ -5013,7 +5014,7 @@ impl<'a> Parser<'a> {
} }
let mac = respan(lo.to(self.prev_span), Mac_ { path: pth, tts: tts }); let mac = respan(lo.to(self.prev_span), Mac_ { path: pth, tts: tts });
Ok((keywords::Invalid.ident(), vec![], ast::ImplItemKind::Macro(mac))) Ok((keywords::Invalid.ident(), vec![], ast::Generics::default(), ast::ImplItemKind::Macro(mac)))
} else { } else {
let (constness, unsafety, abi) = self.parse_fn_front_matter()?; let (constness, unsafety, abi) = self.parse_fn_front_matter()?;
let ident = self.parse_ident()?; let ident = self.parse_ident()?;
@ -5022,8 +5023,7 @@ impl<'a> Parser<'a> {
generics.where_clause = self.parse_where_clause()?; generics.where_clause = self.parse_where_clause()?;
*at_end = true; *at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
Ok((ident, inner_attrs, ast::ImplItemKind::Method(ast::MethodSig { Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(ast::MethodSig {
generics,
abi, abi,
unsafety, unsafety,
constness, constness,

View file

@ -1525,6 +1525,7 @@ impl<'a> State<'a> {
pub fn print_method_sig(&mut self, pub fn print_method_sig(&mut self,
ident: ast::Ident, ident: ast::Ident,
generics: &ast::Generics,
m: &ast::MethodSig, m: &ast::MethodSig,
vis: &ast::Visibility) vis: &ast::Visibility)
-> io::Result<()> { -> io::Result<()> {
@ -1533,7 +1534,7 @@ impl<'a> State<'a> {
m.constness.node, m.constness.node,
m.abi, m.abi,
Some(ident), Some(ident),
&m.generics, &generics,
vis) vis)
} }
@ -1553,7 +1554,7 @@ impl<'a> State<'a> {
if body.is_some() { if body.is_some() {
self.head("")?; self.head("")?;
} }
self.print_method_sig(ti.ident, sig, &ast::Visibility::Inherited)?; self.print_method_sig(ti.ident, &ti.generics, sig, &ast::Visibility::Inherited)?;
if let Some(ref body) = *body { if let Some(ref body) = *body {
self.nbsp()?; self.nbsp()?;
self.print_block_with_attrs(body, &ti.attrs)?; self.print_block_with_attrs(body, &ti.attrs)?;
@ -1592,7 +1593,7 @@ impl<'a> State<'a> {
} }
ast::ImplItemKind::Method(ref sig, ref body) => { ast::ImplItemKind::Method(ref sig, ref body) => {
self.head("")?; self.head("")?;
self.print_method_sig(ii.ident, sig, &ii.vis)?; self.print_method_sig(ii.ident, &ii.generics, sig, &ii.vis)?;
self.nbsp()?; self.nbsp()?;
self.print_block_with_attrs(body, &ii.attrs)?; self.print_block_with_attrs(body, &ii.attrs)?;
} }

View file

@ -543,8 +543,7 @@ pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl
walk_fn_decl(visitor, declaration); walk_fn_decl(visitor, declaration);
visitor.visit_block(body); visitor.visit_block(body);
} }
FnKind::Method(_, sig, _, body) => { FnKind::Method(_, _, _, body) => {
visitor.visit_generics(&sig.generics);
walk_fn_decl(visitor, declaration); walk_fn_decl(visitor, declaration);
visitor.visit_block(body); visitor.visit_block(body);
} }
@ -558,13 +557,13 @@ pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl
pub fn walk_trait_item<'a, V: Visitor<'a>>(visitor: &mut V, trait_item: &'a TraitItem) { pub fn walk_trait_item<'a, V: Visitor<'a>>(visitor: &mut V, trait_item: &'a TraitItem) {
visitor.visit_ident(trait_item.span, trait_item.ident); visitor.visit_ident(trait_item.span, trait_item.ident);
walk_list!(visitor, visit_attribute, &trait_item.attrs); walk_list!(visitor, visit_attribute, &trait_item.attrs);
visitor.visit_generics(&trait_item.generics);
match trait_item.node { match trait_item.node {
TraitItemKind::Const(ref ty, ref default) => { TraitItemKind::Const(ref ty, ref default) => {
visitor.visit_ty(ty); visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, default); walk_list!(visitor, visit_expr, default);
} }
TraitItemKind::Method(ref sig, None) => { TraitItemKind::Method(ref sig, None) => {
visitor.visit_generics(&sig.generics);
walk_fn_decl(visitor, &sig.decl); walk_fn_decl(visitor, &sig.decl);
} }
TraitItemKind::Method(ref sig, Some(ref body)) => { TraitItemKind::Method(ref sig, Some(ref body)) => {
@ -585,6 +584,7 @@ pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, impl_item: &'a ImplIt
visitor.visit_vis(&impl_item.vis); visitor.visit_vis(&impl_item.vis);
visitor.visit_ident(impl_item.span, impl_item.ident); visitor.visit_ident(impl_item.span, impl_item.ident);
walk_list!(visitor, visit_attribute, &impl_item.attrs); walk_list!(visitor, visit_attribute, &impl_item.attrs);
visitor.visit_generics(&impl_item.generics);
match impl_item.node { match impl_item.node {
ImplItemKind::Const(ref ty, ref expr) => { ImplItemKind::Const(ref ty, ref expr) => {
visitor.visit_ty(ty); visitor.visit_ty(ty);

View file

@ -506,6 +506,7 @@ impl<'a> TraitDef<'a> {
vis: ast::Visibility::Inherited, vis: ast::Visibility::Inherited,
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
attrs: Vec::new(), attrs: Vec::new(),
generics: Generics::default(),
node: ast::ImplItemKind::Type(type_def.to_ty(cx, self.span, type_ident, generics)), node: ast::ImplItemKind::Type(type_def.to_ty(cx, self.span, type_ident, generics)),
tokens: None, tokens: None,
} }
@ -921,12 +922,12 @@ impl<'a> MethodDef<'a> {
ast::ImplItem { ast::ImplItem {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
attrs: self.attributes.clone(), attrs: self.attributes.clone(),
generics: fn_generics,
span: trait_.span, span: trait_.span,
vis: ast::Visibility::Inherited, vis: ast::Visibility::Inherited,
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
ident: method_ident, ident: method_ident,
node: ast::ImplItemKind::Method(ast::MethodSig { node: ast::ImplItemKind::Method(ast::MethodSig {
generics: fn_generics,
abi, abi,
unsafety, unsafety,
constness: constness: