Auto merge of #44766 - sunjay:lift_generics, r=nikomatsakis

Move Generics from MethodSig to TraitItem and ImplItem

As part of `rust-impl-period/WG-compiler-traits`, we want to "lift" `Generics` from `MethodSig` into `TraitItem` and `ImplItem`. This is in preparation for adding associated type generics. (https://github.com/rust-lang/rust/issues/44265#issuecomment-331172238)

Currently this change is only made in the AST. In the future, it may also impact the HIR. (Still discussing)

To understand this PR, it's probably best to start from the changes to `ast.rs` and then work your way to the other files to understand the far reaching effects of this change.

r? @nikomatsakis
This commit is contained in:
bors 2017-10-24 01:20:09 +00:00
commit 336624735c
23 changed files with 107 additions and 125 deletions

View File

@ -780,9 +780,7 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
FnKind::ItemFn(_, generics, ..) => {
visitor.visit_generics(generics);
}
FnKind::Method(_, sig, ..) => {
visitor.visit_generics(&sig.generics);
}
FnKind::Method(..) |
FnKind::Closure(_) => {}
}
}
@ -802,6 +800,7 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
visitor.visit_name(trait_item.span, trait_item.name);
walk_list!(visitor, visit_attribute, &trait_item.attrs);
visitor.visit_generics(&trait_item.generics);
match trait_item.node {
TraitItemKind::Const(ref ty, default) => {
visitor.visit_id(trait_item.id);
@ -810,7 +809,6 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
}
TraitItemKind::Method(ref sig, TraitMethod::Required(ref names)) => {
visitor.visit_id(trait_item.id);
visitor.visit_generics(&sig.generics);
visitor.visit_fn_decl(&sig.decl);
for name in names {
visitor.visit_name(name.span, name.node);
@ -852,6 +850,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
ref vis,
ref defaultness,
ref attrs,
ref generics,
ref node,
span
} = *impl_item;
@ -860,6 +859,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
visitor.visit_vis(vis);
visitor.visit_defaultness(defaultness);
walk_list!(visitor, visit_attribute, attrs);
visitor.visit_generics(generics);
match *node {
ImplItemKind::Const(ref ty, body) => {
visitor.visit_id(impl_item.id);

View File

@ -1539,6 +1539,7 @@ impl<'a> LoweringContext<'a> {
hir_id,
name: this.lower_ident(i.ident),
attrs: this.lower_attrs(&i.attrs),
generics: this.lower_generics(&i.generics),
node: match i.node {
TraitItemKind::Const(ref ty, ref default) => {
hir::TraitItemKind::Const(this.lower_ty(ty),
@ -1603,6 +1604,7 @@ impl<'a> LoweringContext<'a> {
hir_id,
name: this.lower_ident(i.ident),
attrs: this.lower_attrs(&i.attrs),
generics: this.lower_generics(&i.generics),
vis: this.lower_visibility(&i.vis, None),
defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
node: match i.node {
@ -1729,7 +1731,6 @@ impl<'a> LoweringContext<'a> {
fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
hir::MethodSig {
generics: self.lower_generics(&sig.generics),
abi: sig.abi,
unsafety: self.lower_unsafety(sig.unsafety),
constness: self.lower_constness(sig.constness),

View File

@ -1295,7 +1295,6 @@ pub struct MethodSig {
pub constness: Constness,
pub abi: Abi,
pub decl: P<FnDecl>,
pub generics: Generics,
}
// The bodies for items are stored "out of line", in a separate
@ -1316,6 +1315,7 @@ pub struct TraitItem {
pub name: Name,
pub hir_id: HirId,
pub attrs: HirVec<Attribute>,
pub generics: Generics,
pub node: TraitItemKind,
pub span: Span,
}
@ -1360,6 +1360,7 @@ pub struct ImplItem {
pub vis: Visibility,
pub defaultness: Defaultness,
pub attrs: HirVec<Attribute>,
pub generics: Generics,
pub node: ImplItemKind,
pub span: Span,
}

View File

@ -880,6 +880,7 @@ impl<'a> State<'a> {
pub fn print_method_sig(&mut self,
name: ast::Name,
m: &hir::MethodSig,
generics: &hir::Generics,
vis: &hir::Visibility,
arg_names: &[Spanned<ast::Name>],
body_id: Option<hir::BodyId>)
@ -889,7 +890,7 @@ impl<'a> State<'a> {
m.constness,
m.abi,
Some(name),
&m.generics,
generics,
vis,
arg_names,
body_id)
@ -905,12 +906,14 @@ impl<'a> State<'a> {
self.print_associated_const(ti.name, &ty, default, &hir::Inherited)?;
}
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref arg_names)) => {
self.print_method_sig(ti.name, sig, &hir::Inherited, arg_names, None)?;
self.print_method_sig(ti.name, sig, &ti.generics, &hir::Inherited, arg_names,
None)?;
self.s.word(";")?;
}
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
self.head("")?;
self.print_method_sig(ti.name, sig, &hir::Inherited, &[], Some(body))?;
self.print_method_sig(ti.name, sig, &ti.generics, &hir::Inherited, &[],
Some(body))?;
self.nbsp()?;
self.end()?; // need to close a box
self.end()?; // need to close a box
@ -938,7 +941,7 @@ impl<'a> State<'a> {
}
hir::ImplItemKind::Method(ref sig, body) => {
self.head("")?;
self.print_method_sig(ii.name, sig, &ii.vis, &[], Some(body))?;
self.print_method_sig(ii.name, sig, &ii.generics, &ii.vis, &[], Some(body))?;
self.nbsp()?;
self.end()?; // need to close a box
self.end()?; // need to close a box

View File

@ -232,8 +232,7 @@ impl_stable_hash_for!(struct hir::MethodSig {
unsafety,
constness,
abi,
decl,
generics
decl
});
impl_stable_hash_for!(struct hir::TypeBinding {
@ -709,6 +708,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::TraitItem {
hir_id: _,
name,
ref attrs,
ref generics,
ref node,
span
} = *self;
@ -716,6 +716,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::TraitItem {
hcx.hash_hir_item_like(attrs, |hcx| {
name.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);
generics.hash_stable(hcx, hasher);
node.hash_stable(hcx, hasher);
span.hash_stable(hcx, hasher);
});
@ -744,6 +745,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::ImplItem {
ref vis,
defaultness,
ref attrs,
ref generics,
ref node,
span
} = *self;
@ -753,6 +755,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::ImplItem {
vis.hash_stable(hcx, hasher);
defaultness.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);
generics.hash_stable(hcx, hasher);
node.hash_stable(hcx, hasher);
span.hash_stable(hcx, hasher);
});

View File

@ -58,11 +58,10 @@ fn item_might_be_inlined(item: &hir::Item) -> bool {
}
fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
sig: &hir::MethodSig,
impl_item: &hir::ImplItem,
impl_src: DefId) -> bool {
if attr::requests_inline(&impl_item.attrs) ||
generics_require_inlining(&sig.generics) {
generics_require_inlining(&impl_item.generics) {
return true
}
if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) {
@ -176,8 +175,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
Some(hir_map::NodeImplItem(impl_item)) => {
match impl_item.node {
hir::ImplItemKind::Const(..) => true,
hir::ImplItemKind::Method(ref sig, _) => {
if generics_require_inlining(&sig.generics) ||
hir::ImplItemKind::Method(..) => {
if generics_require_inlining(&impl_item.generics) ||
attr::requests_inline(&impl_item.attrs) {
true
} else {
@ -293,9 +292,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir::ImplItemKind::Const(_, body) => {
self.visit_nested_body(body);
}
hir::ImplItemKind::Method(ref sig, body) => {
hir::ImplItemKind::Method(_, body) => {
let did = self.tcx.hir.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, sig, impl_item, did) {
if method_might_be_inlined(self.tcx, impl_item, did) {
self.visit_nested_body(body)
}
}

View File

@ -412,7 +412,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
if let hir::TraitItemKind::Method(ref sig, _) = trait_item.node {
self.visit_early_late(
Some(self.hir_map.get_parent(trait_item.id)),
&sig.decl, &sig.generics,
&sig.decl, &trait_item.generics,
|this| intravisit::walk_trait_item(this, trait_item))
} else {
intravisit::walk_trait_item(self, trait_item);
@ -423,7 +423,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
self.visit_early_late(
Some(self.hir_map.get_parent(impl_item.id)),
&sig.decl, &sig.generics,
&sig.decl, &impl_item.generics,
|this| intravisit::walk_impl_item(this, impl_item))
} else {
intravisit::walk_impl_item(self, impl_item);

View File

@ -718,12 +718,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
_: Span,
node_id: NodeId) {
let rib_kind = match function_kind {
FnKind::ItemFn(_, generics, ..) => {
self.visit_generics(generics);
FnKind::ItemFn(..) => {
ItemRibKind
}
FnKind::Method(_, sig, _, _) => {
self.visit_generics(&sig.generics);
MethodRibKind(!sig.decl.has_self())
}
FnKind::Closure(_) => ClosureRibKind(node_id),
@ -1880,7 +1878,7 @@ impl<'a> Resolver<'a> {
}
TraitItemKind::Method(ref sig, _) => {
let type_parameters =
HasTypeParameters(&sig.generics,
HasTypeParameters(&trait_item.generics,
MethodRibKind(!sig.decl.has_self()));
this.with_type_parameter_rib(type_parameters, |this| {
visit::walk_trait_item(this, trait_item)
@ -2099,7 +2097,7 @@ impl<'a> Resolver<'a> {
// We also need a new scope for the method-
// specific type parameters.
let type_parameters =
HasTypeParameters(&sig.generics,
HasTypeParameters(&impl_item.generics,
MethodRibKind(!sig.decl.has_self()));
this.with_type_parameter_rib(type_parameters, |this| {
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>,
id: ast::NodeId,
name: ast::Ident,
generics: &'l ast::Generics,
vis: ast::Visibility,
span: Span) {
debug!("process_method: {}:{}", id, name);
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() {
self.nest_tables(id, |v| {
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.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);
}
@ -1007,6 +1008,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
body.as_ref().map(|x| &**x),
trait_item.id,
trait_item.ident,
&trait_item.generics,
ast::Visibility::Public,
trait_item.span);
}
@ -1066,6 +1068,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
Some(body),
impl_item.id,
impl_item.ident,
&impl_item.generics,
impl_item.vis.clone(),
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,
ident: ast::Ident,
generics: &ast::Generics,
m: &ast::MethodSig,
scx: &SaveContext)
-> Option<Signature> {
if !scx.config.signatures {
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,
@ -895,6 +896,7 @@ fn make_assoc_const_signature(id: NodeId,
fn make_method_signature(id: NodeId,
ident: ast::Ident,
generics: &ast::Generics,
m: &ast::MethodSig,
scx: &SaveContext)
-> Result {
@ -915,7 +917,7 @@ fn make_method_signature(id: NodeId,
let mut sig = name_and_generics(text,
0,
&m.generics,
generics,
id,
ident,
scx)?;

View File

@ -568,15 +568,11 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let num_trait_m_type_params = trait_m_generics.types.len();
if num_impl_m_type_params != num_trait_m_type_params {
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
let span = match tcx.hir.expect_impl_item(impl_m_node_id).node {
ImplItemKind::Method(ref impl_m_sig, _) => {
if impl_m_sig.generics.is_parameterized() {
impl_m_sig.generics.span
} else {
impl_m_span
}
}
_ => bug!("{:?} is not a method", impl_m),
let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
let span = if impl_m_item.generics.is_parameterized() {
impl_m_item.generics.span
} else {
impl_m_span
};
let mut err = struct_span_err!(tcx.sess,

View File

@ -261,19 +261,9 @@ fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let item_node_id = tcx.hir.as_local_node_id(item_def_id).unwrap();
let ast_generics = match tcx.hir.get(item_node_id) {
NodeTraitItem(item) => {
match item.node {
TraitItemKind::Method(ref sig, _) => &sig.generics,
_ => return result
}
}
NodeTraitItem(item) => &item.generics,
NodeImplItem(item) => {
match item.node {
ImplItemKind::Method(ref sig, _) => &sig.generics,
_ => return result
}
}
NodeImplItem(item) => &item.generics,
NodeItem(item) => {
match item.node {
@ -818,12 +808,12 @@ fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
match node {
hir_map::NodeTraitItem(item) => match item.node {
hir::TraitItemKind::Method(ref sig, _) =>
has_late_bound_regions(tcx, &sig.generics, &sig.decl),
has_late_bound_regions(tcx, &item.generics, &sig.decl),
_ => None,
},
hir_map::NodeImplItem(item) => match item.node {
hir::ImplItemKind::Method(ref sig, _) =>
has_late_bound_regions(tcx, &sig.generics, &sig.decl),
has_late_bound_regions(tcx, &item.generics, &sig.decl),
_ => None,
},
hir_map::NodeForeignItem(item) => match item.node {
@ -881,19 +871,9 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let no_generics = hir::Generics::empty();
let ast_generics = match node {
NodeTraitItem(item) => {
match item.node {
TraitItemKind::Method(ref sig, _) => &sig.generics,
_ => &no_generics
}
}
NodeTraitItem(item) => &item.generics,
NodeImplItem(item) => {
match item.node {
ImplItemKind::Method(ref sig, _) => &sig.generics,
_ => &no_generics
}
}
NodeImplItem(item) => &item.generics,
NodeItem(item) => {
match item.node {
@ -1353,19 +1333,9 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let icx = ItemCtxt::new(tcx, def_id);
let no_generics = hir::Generics::empty();
let ast_generics = match node {
NodeTraitItem(item) => {
match item.node {
TraitItemKind::Method(ref sig, _) => &sig.generics,
_ => &no_generics
}
}
NodeTraitItem(item) => &item.generics,
NodeImplItem(item) => {
match item.node {
ImplItemKind::Method(ref sig, _) => &sig.generics,
_ => &no_generics
}
}
NodeImplItem(item) => &item.generics,
NodeItem(item) => {
match item.node {

View File

@ -1141,13 +1141,13 @@ pub struct Method {
pub abi: Abi,
}
impl<'a> Clean<Method> for (&'a hir::MethodSig, hir::BodyId) {
impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) {
fn clean(&self, cx: &DocContext) -> Method {
Method {
generics: self.0.generics.clean(cx),
generics: self.1.clean(cx),
unsafety: self.0.unsafety,
constness: self.0.constness,
decl: (&*self.0.decl, self.1).clean(cx),
decl: (&*self.0.decl, self.2).clean(cx),
abi: self.0.abi
}
}
@ -1380,13 +1380,13 @@ impl Clean<Item> for hir::TraitItem {
default.map(|e| print_const_expr(cx, e)))
}
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
MethodItem((sig, body).clean(cx))
MethodItem((sig, &self.generics, body).clean(cx))
}
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => {
TyMethodItem(TyMethod {
unsafety: sig.unsafety.clone(),
decl: (&*sig.decl, &names[..]).clean(cx),
generics: sig.generics.clean(cx),
generics: self.generics.clean(cx),
abi: sig.abi
})
}
@ -1415,7 +1415,7 @@ impl Clean<Item> for hir::ImplItem {
Some(print_const_expr(cx, expr)))
}
hir::ImplItemKind::Method(ref sig, body) => {
MethodItem((sig, body).clean(cx))
MethodItem((sig, &self.generics, body).clean(cx))
}
hir::ImplItemKind::Type(ref ty) => TypedefItem(Typedef {
type_: ty.clean(cx),

View File

@ -1178,7 +1178,6 @@ pub struct MethodSig {
pub constness: Spanned<Constness>,
pub abi: Abi,
pub decl: P<FnDecl>,
pub generics: Generics,
}
/// Represents an item declaration within a trait declaration,
@ -1190,6 +1189,7 @@ pub struct TraitItem {
pub id: NodeId,
pub ident: Ident,
pub attrs: Vec<Attribute>,
pub generics: Generics,
pub node: TraitItemKind,
pub span: Span,
/// See `Item::tokens` for what this is
@ -1211,6 +1211,7 @@ pub struct ImplItem {
pub vis: Visibility,
pub defaultness: Defaultness,
pub attrs: Vec<Attribute>,
pub generics: Generics,
pub node: ImplItemKind,
pub span: Span,
/// 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 attrs = Vec::new();
let generics = ast::Generics::default();
let vis = ast::Visibility::Inherited;
let span = DUMMY_SP;
let expr_placeholder = || P(ast::Expr {
@ -49,12 +50,12 @@ pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion {
tokens: None,
}))),
ExpansionKind::TraitItems => Expansion::TraitItems(SmallVector::one(ast::TraitItem {
id, span, ident, attrs,
id, span, ident, attrs, generics,
node: ast::TraitItemKind::Macro(mac_placeholder()),
tokens: None,
})),
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()),
defaultness: ast::Defaultness::Final,
tokens: None,

View File

@ -1526,7 +1526,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
span: Span,
_node_id: NodeId) {
// check for const fn declarations
if let FnKind::ItemFn(_, _, _, Spanned { node: ast::Constness::Const, .. }, _, _, _) =
if let FnKind::ItemFn(_, _, Spanned { node: ast::Constness::Const, .. }, _, _, _) =
fn_kind {
gate_feature_post!(&self, const_fn, span, "const fn is unstable");
}
@ -1536,7 +1536,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
// point.
match fn_kind {
FnKind::ItemFn(_, _, _, _, abi, _, _) |
FnKind::ItemFn(_, _, _, abi, _, _) |
FnKind::Method(_, &ast::MethodSig { abi, .. }, _, _) => {
self.check_abi(abi, span);
}

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),
ident: folder.fold_ident(i.ident),
attrs: fold_attrs(i.attrs, folder),
generics: folder.fold_generics(i.generics),
node: match i.node {
TraitItemKind::Const(ty, default) => {
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),
ident: folder.fold_ident(i.ident),
attrs: fold_attrs(i.attrs, folder),
generics: folder.fold_generics(i.generics),
defaultness: i.defaultness,
node: match i.node {
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 {
MethodSig {
generics: folder.fold_generics(sig.generics),
abi: sig.abi,
unsafety: sig.unsafety,
constness: sig.constness,

View File

@ -1287,10 +1287,10 @@ impl<'a> Parser<'a> {
mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> {
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![])?;
self.expect(&token::Semi)?;
(ident, TraitItemKind::Type(bounds, default))
(ident, TraitItemKind::Type(bounds, default), ast::Generics::default())
} else if self.is_const_item() {
self.expect_keyword(keywords::Const)?;
let ident = self.parse_ident()?;
@ -1305,7 +1305,7 @@ impl<'a> Parser<'a> {
self.expect(&token::Semi)?;
None
};
(ident, TraitItemKind::Const(ty, default))
(ident, TraitItemKind::Const(ty, default), ast::Generics::default())
} else if self.token.is_path_start() {
// trait item macro.
// 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 });
(keywords::Invalid.ident(), ast::TraitItemKind::Macro(mac))
(keywords::Invalid.ident(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
} else {
let (constness, unsafety, abi) = self.parse_fn_front_matter()?;
@ -1341,13 +1341,12 @@ impl<'a> Parser<'a> {
// definition...
p.parse_arg_general(false)
})?;
generics.where_clause = self.parse_where_clause()?;
let sig = ast::MethodSig {
unsafety,
constness,
decl: d,
generics,
abi,
};
@ -1370,13 +1369,14 @@ impl<'a> Parser<'a> {
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 {
id: ast::DUMMY_NODE_ID,
ident: name,
attrs,
generics,
node,
span: lo.to(self.prev_span),
tokens: None,
@ -4901,12 +4901,12 @@ impl<'a> Parser<'a> {
let lo = self.span;
let vis = self.parse_visibility(false)?;
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()?;
self.expect(&token::Eq)?;
let typ = self.parse_ty()?;
self.expect(&token::Semi)?;
(name, ast::ImplItemKind::Type(typ))
(name, ast::ImplItemKind::Type(typ), ast::Generics::default())
} else if self.is_const_item() {
self.expect_keyword(keywords::Const)?;
let name = self.parse_ident()?;
@ -4915,11 +4915,11 @@ impl<'a> Parser<'a> {
self.expect(&token::Eq)?;
let expr = self.parse_expr()?;
self.expect(&token::Semi)?;
(name, ast::ImplItemKind::Const(typ, expr))
(name, ast::ImplItemKind::Const(typ, expr), ast::Generics::default())
} 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);
(name, node)
(name, node, generics)
};
Ok(ImplItem {
@ -4929,6 +4929,7 @@ impl<'a> Parser<'a> {
vis,
defaultness,
attrs,
generics,
node,
tokens: None,
})
@ -4986,7 +4987,8 @@ impl<'a> Parser<'a> {
/// Parse a method or a macro invocation in a trait impl.
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!
if self.token.is_path_start() {
// Method macro.
@ -5013,7 +5015,8 @@ impl<'a> Parser<'a> {
}
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 {
let (constness, unsafety, abi) = self.parse_fn_front_matter()?;
let ident = self.parse_ident()?;
@ -5022,8 +5025,7 @@ impl<'a> Parser<'a> {
generics.where_clause = self.parse_where_clause()?;
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
Ok((ident, inner_attrs, ast::ImplItemKind::Method(ast::MethodSig {
generics,
Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(ast::MethodSig {
abi,
unsafety,
constness,

View File

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

View File

@ -31,7 +31,7 @@ use codemap::Spanned;
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum FnKind<'a> {
/// fn foo() or extern "Abi" fn foo()
ItemFn(Ident, &'a Generics, Unsafety, Spanned<Constness>, Abi, &'a Visibility, &'a Block),
ItemFn(Ident, Unsafety, Spanned<Constness>, Abi, &'a Visibility, &'a Block),
/// fn foo(&self)
Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a Block),
@ -247,7 +247,8 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_expr(expr);
}
ItemKind::Fn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
visitor.visit_fn(FnKind::ItemFn(item.ident, generics, unsafety,
visitor.visit_generics(generics);
visitor.visit_fn(FnKind::ItemFn(item.ident, unsafety,
constness, abi, &item.vis, body),
declaration,
item.span,
@ -538,13 +539,11 @@ pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl
where V: Visitor<'a>,
{
match kind {
FnKind::ItemFn(_, generics, _, _, _, _, body) => {
visitor.visit_generics(generics);
FnKind::ItemFn(_, _, _, _, _, body) => {
walk_fn_decl(visitor, declaration);
visitor.visit_block(body);
}
FnKind::Method(_, sig, _, body) => {
visitor.visit_generics(&sig.generics);
FnKind::Method(_, _, _, body) => {
walk_fn_decl(visitor, declaration);
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) {
visitor.visit_ident(trait_item.span, trait_item.ident);
walk_list!(visitor, visit_attribute, &trait_item.attrs);
visitor.visit_generics(&trait_item.generics);
match trait_item.node {
TraitItemKind::Const(ref ty, ref default) => {
visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, default);
}
TraitItemKind::Method(ref sig, None) => {
visitor.visit_generics(&sig.generics);
walk_fn_decl(visitor, &sig.decl);
}
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_ident(impl_item.span, impl_item.ident);
walk_list!(visitor, visit_attribute, &impl_item.attrs);
visitor.visit_generics(&impl_item.generics);
match impl_item.node {
ImplItemKind::Const(ref ty, ref expr) => {
visitor.visit_ty(ty);

View File

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

View File

@ -370,9 +370,7 @@ impl Foo {
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
// FIXME(michaelwoerister): This is curious but an unused lifetime parameter doesn't seem to
// show up in any of the derived data structures.
#[rustc_clean(cfg="cfail2", except="Hir,HirBody")]
#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
@ -395,7 +393,7 @@ impl Foo {
impl Foo {
#[rustc_clean(
cfg="cfail2",
except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,TypeOfItem",
except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,TypeOfItem,TypeckTables",
)]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
@ -441,7 +439,8 @@ impl Foo {
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_clean(cfg="cfail2", except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,TypeOfItem")]
#[rustc_clean(cfg="cfail2", except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,\
TypeOfItem,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
@ -462,7 +461,7 @@ impl Foo {
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_clean(cfg="cfail2", except="Hir,HirBody,PredicatesOfItem")]
#[rustc_clean(cfg="cfail2", except="Hir,HirBody,PredicatesOfItem,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]

View File

@ -26,10 +26,10 @@
miri = "Broken"
# ping @Manishearth @llogiq @mcarton @oli-obk
clippy = "Compiling"
clippy = "Broken"
# ping @nrc
rls = "Testing"
rls = "Broken"
# ping @nrc
rustfmt = "Testing"
rustfmt = "Broken"