diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 0c220ab8766..eb41a26fa77 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -838,7 +838,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, if !any_types { encode_symbol(ecx, rbml_w, m.def_id.node); } - encode_method_argument_names(rbml_w, ast_method.pe_fn_decl()); + encode_method_argument_names(rbml_w, &ast_method.pe_sig().decl); } } @@ -1383,7 +1383,7 @@ fn encode_info_for_item(ecx: &EncodeContext, 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()); + encode_method_argument_names(rbml_w, &*m.pe_sig().decl); } ast::TypeTraitItem(..) => { diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 5b5e5b6555b..02f2908a9e6 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -91,7 +91,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { visit::FkItemFn(_, _, fn_style, _) => (true, fn_style == ast::Unsafety::Unsafe), visit::FkMethod(_, method) => - (true, method.pe_unsafety() == ast::Unsafety::Unsafe), + (true, method.pe_sig().unsafety == ast::Unsafety::Unsafe), _ => (false, false), }; diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index cf3715bc3fb..823acdc1691 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -841,7 +841,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { ast_map::NodeItem(ref item) => { match item.node { ast::ItemFn(ref fn_decl, pur, _, ref gen, _) => { - Some((&**fn_decl, gen, pur, item.ident, None, item.span)) + Some((fn_decl, gen, pur, item.ident, None, item.span)) }, _ => None } @@ -849,11 +849,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { ast_map::NodeImplItem(item) => { match item.node { ast::MethodImplItem(ref m) => { - Some((m.pe_fn_decl(), - m.pe_generics(), - m.pe_unsafety(), + Some((&m.pe_sig().decl, + &m.pe_sig().generics, + m.pe_sig().unsafety, item.ident, - Some(&m.pe_explicit_self().node), + Some(&m.pe_sig().explicit_self.node), item.span)) } ast::TypeImplItem(_) => None, @@ -862,11 +862,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { ast_map::NodeTraitItem(item) => { match item.node { ast::ProvidedMethod(ref m) => { - Some((m.pe_fn_decl(), - m.pe_generics(), - m.pe_unsafety(), + Some((&m.pe_sig().decl, + &m.pe_sig().generics, + m.pe_sig().unsafety, item.ident, - Some(&m.pe_explicit_self().node), + Some(&m.pe_sig().explicit_self.node), item.span)) } _ => None @@ -1732,7 +1732,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt, ast_map::NodeImplItem(ii) => { match ii.node { ast::MethodImplItem(ref m) => { - taken.push_all(&m.pe_generics().lifetimes); + taken.push_all(&m.pe_sig().generics.lifetimes); Some(ii.id) } ast::TypeImplItem(_) => None, diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index fd6b28fd292..75e9c60698b 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -57,7 +57,7 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method, impl_item: &ast::ImplItem, impl_src: ast::DefId) -> bool { if attr::requests_inline(&impl_item.attrs) || - generics_require_inlining(method.pe_generics()) { + generics_require_inlining(&method.pe_sig().generics) { return true } if is_local(impl_src) { @@ -191,7 +191,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { Some(ast_map::NodeImplItem(impl_item)) => { match impl_item.node { ast::MethodImplItem(ref method) => { - if generics_require_inlining(method.pe_generics()) || + if generics_require_inlining(&method.pe_sig().generics) || attr::requests_inline(&impl_item.attrs) { true } else { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index e02f7861285..32d52bcbf74 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -149,7 +149,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { }) } visit::FkMethod(_, m) => { - self.visit_early_late(subst::FnSpace, m.pe_generics(), |this| { + self.visit_early_late(subst::FnSpace, &m.pe_sig().generics, |this| { visit::walk_fn(this, fk, fd, b, s) }) } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 259a9acadc6..687b4cb8723 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -46,7 +46,7 @@ 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::{self, is_shift_binop, local_def}; +use syntax::ast_util::{self, is_shift_binop, local_def, PostExpansionMethod}; use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::{self, Span}; use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType}; @@ -1319,7 +1319,7 @@ impl LintPass for UnsafeCode { cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"), visit::FkMethod(_, m) => { - if let ast::MethDecl(_, _, _, ast::Unsafety::Unsafe, _, _) = *m { + if m.pe_sig().unsafety == ast::Unsafety::Unsafe { cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method") } }, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9cb9c1f2f85..9b069962de4 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -275,7 +275,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { match impl_item.node { ast::MethodImplItem(ref method) => { let meth_public = - match method.pe_explicit_self().node { + match method.pe_sig().explicit_self.node { ast::SelfStatic => public_ty, _ => true, } && impl_item.vis == ast::Public; @@ -1355,7 +1355,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { for impl_item in impl_items { match impl_item.node { ast::MethodImplItem(ref method) => { - if method.pe_explicit_self().node == + if method.pe_sig().explicit_self.node == ast::SelfStatic && self.exported_items .contains(&impl_item.id) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 67675a5a1ae..296a9794f1c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -243,8 +243,8 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { ItemRibKind } visit::FkMethod(_, method) => { - self.visit_generics(method.pe_generics()); - self.visit_explicit_self(method.pe_explicit_self()); + self.visit_generics(&method.pe_sig().generics); + self.visit_explicit_self(&method.pe_sig().explicit_self); MethodRibKind } visit::FkFnBlock(..) => ClosureRibKind(node_id) @@ -2814,13 +2814,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // FIXME #4951: Do we need a node ID here? let type_parameters = match trait_item.node { - ast::RequiredMethod(ref ty_m) => { - HasTypeParameters(&ty_m.generics, + ast::RequiredMethod(ref sig) => { + HasTypeParameters(&sig.generics, FnSpace, MethodRibKind) } ast::ProvidedMethod(ref m) => { - HasTypeParameters(m.pe_generics(), + HasTypeParameters(&m.pe_sig().generics, FnSpace, MethodRibKind) } @@ -3075,7 +3075,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // We also need a new scope for the method- // specific type parameters. let type_parameters = - HasTypeParameters(method.pe_generics(), + HasTypeParameters(&method.pe_sig().generics, FnSpace, MethodRibKind); this.with_type_parameter_rib(type_parameters, |this| { @@ -3956,11 +3956,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let explicit_self = match this.ast_map.get(did.node) { ast_map::NodeTraitItem(trait_item) => match trait_item.node { ast::RequiredMethod(ref m) => &m.explicit_self, - ast::ProvidedMethod(ref m) => m.pe_explicit_self(), + ast::ProvidedMethod(ref m) => &m.pe_sig().explicit_self, _ => return false }, ast_map::NodeImplItem(impl_item) => match impl_item.node { - ast::MethodImplItem(ref m) => m.pe_explicit_self(), + ast::MethodImplItem(ref m) => &m.pe_sig().explicit_self, _ => return false }, _ => return false diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 95365020964..2b1def22ed9 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -382,21 +382,21 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { decl_id, scope_id); - self.process_formals(&method.pe_fn_decl().inputs, qualname); + self.process_formals(&method.pe_sig().decl.inputs, qualname); // walk arg and return types - for arg in &method.pe_fn_decl().inputs { + for arg in &method.pe_sig().decl.inputs { self.visit_ty(&*arg.ty); } - if let ast::Return(ref ret_ty) = method.pe_fn_decl().output { + if let ast::Return(ref ret_ty) = method.pe_sig().decl.output { self.visit_ty(&**ret_ty); } // walk the fn body self.nest(id, |v| v.visit_block(&*method.pe_body())); - self.process_generic_params(method.pe_generics(), + self.process_generic_params(&method.pe_sig().generics, span, qualname, id); diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 0b98beb53c5..11495c7e6a3 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -1292,7 +1292,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match item.node { ast::ItemFn(ref fn_decl, _, _, ref generics, ref top_level_block) => { - (item.ident, &**fn_decl, generics, &**top_level_block, item.span, true) + (item.ident, fn_decl, generics, &**top_level_block, item.span, true) } _ => { cx.sess().span_bug(item.span, @@ -1308,8 +1308,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } (impl_item.ident, - method.pe_fn_decl(), - method.pe_generics(), + &method.pe_sig().decl, + &method.pe_sig().generics, method.pe_body(), impl_item.span, true) @@ -1326,7 +1326,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ast::ExprClosure(_, ref fn_decl, ref top_level_block) => { let name = format!("fn{}", token::gensym("fn")); let name = token::str_to_ident(&name[..]); - (name, &**fn_decl, + (name, fn_decl, // This is not quite right. It should actually inherit // the generics of the enclosing function. &empty_generics, @@ -1347,8 +1347,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } (trait_item.ident, - method.pe_fn_decl(), - method.pe_generics(), + &method.pe_sig().decl, + &method.pe_sig().generics, method.pe_body(), trait_item.span, true) diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index 6c1401a4c02..eacc40edcc6 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -149,11 +149,11 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) 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() { + mth.pe_sig().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_sig().decl, &*mth.pe_body(), llfn, empty_substs, diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index aea922d9f9f..8df086fd232 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -80,13 +80,13 @@ pub fn trans_impl(ccx: &CrateContext, for impl_item in impl_items { match impl_item.node { ast::MethodImplItem(ref method) => { - if method.pe_generics().ty_params.len() == 0 { + if method.pe_sig().generics.ty_params.len() == 0 { 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, impl_item.id); let empty_substs = tcx.mk_substs(Substs::trans_empty()); trans_fn(ccx, - method.pe_fn_decl(), + &method.pe_sig().decl, method.pe_body(), llfn, empty_substs, diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 1af783373f9..80271a72c68 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -223,7 +223,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let needs_body = setup_lldecl(d, &impl_item.attrs); if needs_body { trans_fn(ccx, - mth.pe_fn_decl(), + &mth.pe_sig().decl, mth.pe_body(), d, psubsts, @@ -243,7 +243,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let d = mk_lldecl(abi::Rust); let needs_body = setup_lldecl(d, &trait_item.attrs); if needs_body { - trans_fn(ccx, mth.pe_fn_decl(), mth.pe_body(), d, + trans_fn(ccx, &mth.pe_sig().decl, mth.pe_body(), d, psubsts, trait_item.id, &[]); } d diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 9c2bc4da64f..28e7027b212 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1442,22 +1442,19 @@ struct SelfInfo<'a, 'tcx> { } pub fn ty_of_method<'tcx>(this: &AstConv<'tcx>, - unsafety: ast::Unsafety, - untransformed_self_ty: Ty<'tcx>, - explicit_self: &ast::ExplicitSelf, - decl: &ast::FnDecl, - abi: abi::Abi) + sig: &ast::MethodSig, + untransformed_self_ty: Ty<'tcx>) -> (ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) { let self_info = Some(SelfInfo { untransformed_self_ty: untransformed_self_ty, - explicit_self: explicit_self, + explicit_self: &sig.explicit_self, }); let (bare_fn_ty, optional_explicit_self_category) = ty_of_method_or_bare_fn(this, - unsafety, - abi, + sig.unsafety, + sig.abi, self_info, - decl); + &sig.decl); (bare_fn_ty, optional_explicit_self_category.unwrap()) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3ffc36d3acb..470e1d54c7f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -867,7 +867,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, debug!("check_method_body: fty={}", fty.repr(ccx.tcx)); check_bare_fn(ccx, - &*method.pe_fn_decl(), + &*method.pe_sig().decl, &*method.pe_body(), id, span, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index b90129f7ab7..a2ca228b11a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -621,152 +621,52 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } -fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - trait_id: ast::NodeId, - trait_def: &ty::TraitDef<'tcx>, - trait_predicates: &ty::GenericPredicates<'tcx>) { - let tcx = ccx.tcx; - if let ast_map::NodeItem(item) = tcx.map.get(trait_id) { - if let ast::ItemTrait(_, _, _, ref trait_items) = item.node { - // 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.node { - ast::RequiredMethod(_) | - ast::ProvidedMethod(_) => { - 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, - trait_item.id, - trait_item.ident, - &m.explicit_self, - m.abi, - &m.generics, - &m.unsafety, - &*m.decl) - } - ast::ProvidedMethod(ref m) => { - ty_method_of_trait_method( - ccx, - trait_id, - &trait_def.generics, - &trait_predicates, - 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(..) => unreachable!() - }); +fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, + container: ImplOrTraitItemContainer, + sig: &ast::MethodSig, + 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>) { + let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics); - debug!("ty_method_of_trait_method yielded {} for method {} of trait {}", - ty_method.repr(ccx.tcx), - trait_item.repr(ccx.tcx), - local_def(trait_id).repr(ccx.tcx)); + let ty_generic_predicates = + ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates); - make_method_ty(ccx, &*ty_method); + let (fty, explicit_self_category) = + astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)), + sig, untransformed_rcvr_ty); - tcx.impl_or_trait_items - .borrow_mut() - .insert(ty_method.def_id, ty::MethodTraitItem(ty_method)); - } - ast::TypeTraitItem(..) => { - let trait_did = local_def(trait_id); - let associated_type = ty::AssociatedType { - name: trait_item.ident.name, - vis: ast::Public, - def_id: local_def(trait_item.id), - container: TraitContainer(trait_did), - }; + let def_id = local_def(id); + let ty_method = ty::Method::new(ident.name, + ty_generics, + ty_generic_predicates, + fty, + explicit_self_category, + vis, + def_id, + container, + None); - let trait_item = ty::TypeTraitItem(Rc::new(associated_type)); - tcx.impl_or_trait_items - .borrow_mut() - .insert(associated_type.def_id, trait_item); - } - } - } + let fty = ty::mk_bare_fn(ccx.tcx, Some(def_id), + ccx.tcx.mk_bare_fn(ty_method.fty.clone())); + debug!("method {} (id {}) has type {}", + ident.repr(ccx.tcx), id, fty.repr(ccx.tcx)); + ccx.tcx.tcache.borrow_mut().insert(def_id,TypeScheme { + generics: ty_method.generics.clone(), + ty: fty + }); + ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone()); - // Add an entry mapping - 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) - } - ast::TypeTraitItem(..) => { - ty::TypeTraitItemId(def_id) - } - } - }).collect()); + write_ty_to_tcx(ccx.tcx, id, fty); - let trait_def_id = local_def(trait_id); - tcx.trait_item_def_ids.borrow_mut().insert(trait_def_id, trait_item_def_ids); - } - } + debug!("writing method type: def_id={:?} mty={}", + def_id, ty_method.repr(ccx.tcx)); - fn make_method_ty<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, m: &ty::Method<'tcx>) { - ccx.tcx.tcache.borrow_mut().insert( - m.def_id, - TypeScheme { - generics: m.generics.clone(), - ty: ty::mk_bare_fn(ccx.tcx, Some(m.def_id), ccx.tcx.mk_bare_fn(m.fty.clone())) - }); - ccx.tcx.predicates.borrow_mut().insert( - m.def_id, - m.predicates.clone()); - } - - fn ty_method_of_trait_method<'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_ident: ast::Ident, - m_explicit_self: &ast::ExplicitSelf, - m_abi: abi::Abi, - m_generics: &ast::Generics, - m_unsafety: &ast::Unsafety, - m_decl: &ast::FnDecl) - -> ty::Method<'tcx> - { - let ty_generics = - ty_generics_for_fn(ccx, m_generics, trait_generics); - - let ty_generic_predicates = - ty_generic_predicates_for_fn(ccx, m_generics, trait_bounds); - - let (fty, explicit_self_category) = { - let trait_self_ty = ty::mk_self_type(ccx.tcx); - astconv::ty_of_method(&ccx.icx(&(trait_bounds, m_generics)), - *m_unsafety, - trait_self_ty, - m_explicit_self, - m_decl, - m_abi) - }; - - ty::Method::new( - 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), - TraitContainer(local_def(trait_id)), - None - ) - } + ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id, + ty::MethodTraitItem(Rc::new(ty_method))); } fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, @@ -809,20 +709,19 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - trait_def: &ty::TraitDef<'tcx>, + container: ImplOrTraitItemContainer, ident: ast::Ident, - id: ast::NodeId) + id: ast::NodeId, + vis: ast::Visibility) { let associated_type = Rc::new(ty::AssociatedType { name: ident.name, - vis: ast::Public, + vis: vis, def_id: local_def(id), - container: TraitContainer(trait_def.trait_ref.def_id), + container: container }); - ccx.tcx - .impl_or_trait_items - .borrow_mut() - .insert(associated_type.def_id, ty::TypeTraitItem(associated_type)); + ccx.tcx.impl_or_trait_items.borrow_mut() + .insert(local_def(id), ty::TypeTraitItem(associated_type)); } fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, @@ -830,9 +729,8 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, 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 + rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) + where I: Iterator { debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={}, rcvr_ty_predicates={})", untransformed_rcvr_ty.repr(ccx.tcx), @@ -841,87 +739,20 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, let tcx = ccx.tcx; let mut seen_methods = FnvHashSet(); - for (m, id, ident, vis, span) in methods { + for (sig, id, ident, vis, span) in methods { if !seen_methods.insert(ident.name) { - span_err!(tcx.sess, span, E0201, "duplicate method in trait impl"); + span_err!(tcx.sess, span, E0201, "duplicate method"); } - 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 {}", - ident.repr(tcx), - id, - fty.repr(tcx)); - tcx.tcache.borrow_mut().insert( - m_def_id, - TypeScheme { - generics: mty.generics.clone(), - ty: fty - }); - tcx.predicates.borrow_mut().insert(m_def_id, mty.predicates.clone()); - - write_ty_to_tcx(tcx, id, fty); - - debug!("writing method type: def_id={:?} mty={}", - mty.def_id, mty.repr(ccx.tcx)); - - tcx.impl_or_trait_items - .borrow_mut() - .insert(mty.def_id, ty::MethodTraitItem(mty)); - } - - 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>, - rcvr_visibility: ast::Visibility) - -> ty::Method<'tcx> - { - let m_ty_generics = - ty_generics_for_fn(ccx, m.pe_generics(), rcvr_ty_generics); - - let m_ty_generic_predicates = - ty_generic_predicates_for_fn(ccx, m.pe_generics(), rcvr_ty_predicates); - - let (fty, explicit_self_category) = - astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, m.pe_generics())), - m.pe_unsafety(), - untransformed_rcvr_ty, - m.pe_explicit_self(), - &*m.pe_fn_decl(), - m.pe_abi()); - - // if the method specifies a visibility, use that, otherwise - // 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 = vis.inherit_from(rcvr_visibility); - - ty::Method::new(ident.name, - m_ty_generics, - m_ty_generic_predicates, - fty, - explicit_self_category, - method_vis, - local_def(id), - container, - None) + convert_method(ccx, + container, + sig, + id, + ident, + vis, + untransformed_rcvr_ty, + rcvr_ty_generics, + rcvr_ty_predicates); } } @@ -1013,6 +844,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { it.vis }; + // Convert all the associated types. for impl_item in impl_items { match impl_item.node { ast::MethodImplItem(_) => {} @@ -1022,6 +854,9 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { "associated items are not allowed in inherent impls"); } + convert_associated_type(ccx, ImplContainer(local_def(it.id)), + impl_item.ident, impl_item.id, impl_item.vis); + let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty); tcx.tcache.borrow_mut().insert(local_def(impl_item.id), TypeScheme { @@ -1031,17 +866,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { tcx.predicates.borrow_mut().insert(local_def(impl_item.id), ty::GenericPredicates::empty()); write_ty_to_tcx(tcx, impl_item.id, typ); - - let associated_type = Rc::new(ty::AssociatedType { - 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(impl_item.id), - ty::TypeTraitItem(associated_type)); } } } @@ -1049,7 +873,12 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { 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)) + // if the method specifies a visibility, use that, otherwise + // 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 = ii.vis.inherit_from(parent_visibility); + Some((m.pe_sig(), ii.id, ii.ident, method_vis, ii.span)) } ast::TypeImplItem(_) => None } @@ -1059,8 +888,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { methods, selfty, &ty_generics, - &ty_predicates, - parent_visibility); + &ty_predicates); for impl_item in impl_items { match impl_item.node { @@ -1070,7 +898,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { &BindingRscope::new(), ccx.method_ty(impl_item.id), selfty, - method.pe_explicit_self(), + &method.pe_sig().explicit_self, body_id); } ast::TypeImplItem(_) => {} @@ -1095,63 +923,68 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { let _: Result<(), ErrorReported> = // any error is already reported, can ignore ccx.ensure_super_predicates(it.span, local_def(it.id)); convert_trait_predicates(ccx, it); - let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(it.id)); + let trait_predicates = ty::lookup_predicates(tcx, local_def(it.id)); 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)) - } + // Convert all the associated types. + for trait_item in trait_items { + match trait_item.node { ast::RequiredMethod(_) | - ast::TypeTraitItem(..) => None, + ast::ProvidedMethod(_) => {} + ast::TypeTraitItem(..) => { + convert_associated_type(ccx, TraitContainer(local_def(it.id)), + trait_item.ident, trait_item.id, ast::Public); + } } + }; + + let methods = trait_items.iter().filter_map(|ti| { + let sig = match ti.node { + ast::RequiredMethod(ref sig) => sig, + ast::ProvidedMethod(ref m) => m.pe_sig(), + ast::TypeTraitItem(..) => return None, + }; + Some((sig, ti.id, ti.ident, ast::Inherited, ti.span)) }); - // Run convert_methods on the provided methods. - let untransformed_rcvr_ty = ty::mk_self_type(tcx); + + // Run convert_methods on the trait methods. convert_methods(ccx, TraitContainer(local_def(it.id)), methods, - untransformed_rcvr_ty, + ty::mk_self_type(tcx), &trait_def.generics, - &trait_predicates, - it.vis); + &trait_predicates); - // We need to do this *after* converting methods, since - // convert_methods produces a tcache entry that is wrong for - // static trait methods. This is somewhat unfortunate. - collect_trait_methods(ccx, it.id, &*trait_def, &trait_predicates); + // Add an entry mapping + 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) + } + ast::TypeTraitItem(..) => { + ty::TypeTraitItemId(def_id) + } + } + }).collect()); + tcx.trait_item_def_ids.borrow_mut().insert(local_def(it.id), trait_item_def_ids); // This must be done after `collect_trait_methods` so that // 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.node { - ast::RequiredMethod(ref type_method) => { - let rscope = BindingRscope::new(); - check_method_self_type(ccx, - &rscope, - ccx.method_ty(trait_item.id), - self_type, - &type_method.explicit_self, - it.id) - } - ast::ProvidedMethod(ref method) => { - check_method_self_type(ccx, - &BindingRscope::new(), - ccx.method_ty(trait_item.id), - self_type, - method.pe_explicit_self(), - it.id) - } - ast::TypeTraitItem(..) => { - convert_associated_type(ccx, - &*trait_def, - trait_item.ident, - trait_item.id); - } - } + let sig = match trait_item.node { + ast::RequiredMethod(ref sig) => sig, + ast::ProvidedMethod(ref method) => method.pe_sig(), + ast::TypeTraitItem(..) => continue + }; + check_method_self_type(ccx, + &BindingRscope::new(), + ccx.method_ty(trait_item.id), + ty::mk_self_type(tcx), + &sig.explicit_self, + it.id) } }, ast::ItemStruct(ref struct_def, _) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 202b5f59fb7..05139bf1eab 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -951,8 +951,8 @@ pub struct Method { impl Clean 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 { + let all_inputs = &self.pe_sig().decl.inputs; + let inputs = match self.pe_sig().explicit_self.node { ast::SelfStatic => &**all_inputs, _ => &all_inputs[1..] }; @@ -960,15 +960,15 @@ impl Clean for ast::Method { inputs: Arguments { values: inputs.clean(cx), }, - output: self.pe_fn_decl().output.clean(cx), + output: self.pe_sig().decl.output.clean(cx), attrs: Vec::new() }; Method { - generics: self.pe_generics().clean(cx), - self_: self.pe_explicit_self().node.clean(cx), - unsafety: self.pe_unsafety().clone(), + generics: self.pe_sig().generics.clean(cx), + self_: self.pe_sig().explicit_self.node.clean(cx), + unsafety: self.pe_sig().unsafety.clone(), decl: decl, - abi: self.pe_abi() + abi: self.pe_sig().abi } } } @@ -982,7 +982,7 @@ pub struct TyMethod { pub abi: abi::Abi } -impl Clean for ast::TypeMethod { +impl Clean for ast::MethodSig { fn clean(&self, cx: &DocContext) -> TyMethod { let inputs = match self.explicit_self.node { ast::SelfStatic => &*self.decl.inputs, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bc1767fa3a4..0a08b0b1207 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1058,10 +1058,10 @@ pub struct TypeField { pub span: Span, } -/// Represents a required method in a trait declaration, -/// one without a default implementation +/// Represents a method's signature in a trait declaration, +/// or in an implementation. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct TypeMethod { +pub struct MethodSig { pub unsafety: Unsafety, pub abi: Abi, pub decl: P, @@ -1084,7 +1084,7 @@ pub struct TraitItem { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum TraitItem_ { - RequiredMethod(TypeMethod), + RequiredMethod(MethodSig), ProvidedMethod(Method), TypeTraitItem(TyParamBounds, Option>), } @@ -1419,12 +1419,7 @@ pub type ExplicitSelf = Spanned; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Method { /// Represents a method declaration - MethDecl(Generics, - Abi, - ExplicitSelf, - Unsafety, - P, - P), + MethDecl(MethodSig, P), /// Represents a macro in method position MethMac(Mac), } diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 053c3153340..345ccf902cd 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -162,7 +162,7 @@ impl<'a> FnLikeNode<'a> { 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_sig().decl, |c: ClosureParts<'a>| c.decl) } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 673ea4ac431..91ddc8beec8 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::Abi; use ast::*; use ast; use ast_util; @@ -461,7 +460,7 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { self.visit_generics_helper(generics) } visit::FkMethod(_, m) => { - self.visit_generics_helper(m.pe_generics()) + self.visit_generics_helper(&m.pe_sig().generics) } visit::FkFnBlock => {} } @@ -653,11 +652,7 @@ 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_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_sig<'a>(&'a self) -> &'a ast::MethodSig; fn pe_body<'a>(&'a self) -> &'a ast::Block; } @@ -676,18 +671,8 @@ macro_rules! mf_method{ impl PostExpansionMethod for Method { - mf_method! { - pe_generics,&'a ast::Generics, - MethDecl(ref generics,_,_,_,_,_),generics - } - mf_method! { pe_abi,Abi,MethDecl(_,abi,_,_,_,_),abi } - mf_method! { - pe_explicit_self,&'a ast::ExplicitSelf, - 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_sig, &'a ast::MethodSig,MethDecl(ref sig, _), sig } + mf_method! { pe_body, &'a ast::Block,MethDecl(_, ref body), body } } #[cfg(test)] diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index a4962afff3c..d4b0f7d1dcb 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -724,13 +724,13 @@ impl<'a> MethodDef<'a> { span: trait_.span, vis: ast::Inherited, ident: method_ident, - node: ast::MethodImplItem( - ast::MethDecl(fn_generics, - abi, - explicit_self, - ast::Unsafety::Normal, - fn_decl, - body_block)) + node: ast::MethodImplItem(ast::MethDecl(ast::MethodSig { + generics: fn_generics, + abi: abi, + explicit_self: explicit_self, + unsafety: ast::Unsafety::Normal, + decl: fn_decl + }, body_block)) }) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5fb0126cdd0..fa0b747f45b 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1393,15 +1393,16 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { fn fold_method(&mut self, m: ast::Method) -> ast::Method { match m { - ast::MethDecl(generics, abi, explicit_self, fn_style, decl, body) => { + ast::MethDecl(sig, 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) + = expand_and_rename_fn_decl_and_block(sig.decl, body, self); + ast::MethDecl(ast::MethodSig { + generics: self.fold_generics(sig.generics), + abi: sig.abi, + explicit_self: self.fold_explicit_self(sig.explicit_self), + unsafety: sig.unsafety, + decl: rewritten_fn_decl + }, rewritten_body) } ast::MethMac(mac) => ast::MethMac(mac) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d99f1600cb3..d7982ef8399 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -977,15 +977,7 @@ pub fn noop_fold_trait_item(i: P, folder: &mut T) 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) - }) - } + RequiredMethod(sig) => RequiredMethod(noop_fold_method_sig(sig, folder)), ProvidedMethod(m) => ProvidedMethod(folder.fold_method(m)), TypeTraitItem(bounds, default) => { TypeTraitItem(folder.fold_bounds(bounds), @@ -1110,23 +1102,24 @@ pub fn noop_fold_foreign_item(ni: P, folder: &mut T) -> // Default fold over a method. pub fn noop_fold_method(method: Method, folder: &mut T) -> Method { match method { - MethDecl(generics, - abi, - explicit_self, - unsafety, - decl, - body) => { - MethDecl(folder.fold_generics(generics), - abi, - folder.fold_explicit_self(explicit_self), - unsafety, - folder.fold_fn_decl(decl), + MethDecl(sig, body) => { + MethDecl(noop_fold_method_sig(sig, folder), folder.fold_block(body)) }, MethMac(mac) => MethMac(folder.fold_mac(mac)) } } +pub fn noop_fold_method_sig(sig: MethodSig, folder: &mut T) -> MethodSig { + MethodSig { + generics: folder.fold_generics(sig.generics), + abi: sig.abi, + explicit_self: folder.fold_explicit_self(sig.explicit_self), + unsafety: sig.unsafety, + decl: folder.fold_fn_decl(sig.decl) + } +} + pub fn noop_fold_pat(p: P, folder: &mut T) -> P { p.map(|Pat {id, node, span}| Pat { id: folder.new_id(id), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a38508d2cf5..2e77bd6df18 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -51,8 +51,7 @@ use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{TtDelimited, TtSequence, TtToken}; use ast::{TupleVariantKind, Ty, Ty_, TypeBinding}; -use ast::{TyFixedLengthVec, TyBareFn}; -use ast::{TyTypeof, TyInfer, TypeMethod}; +use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer}; use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr}; use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq}; use ast::{TypeImplItem, TypeTraitItem}; @@ -1341,31 +1340,27 @@ impl<'a> Parser<'a> { }); p.parse_where_clause(&mut generics); + let sig = ast::MethodSig { + unsafety: style, + decl: d, + generics: generics, + abi: abi, + explicit_self: explicit_self, + }; let hi = p.last_span.hi; let node = match p.token { token::Semi => { p.bump(); debug!("parse_trait_methods(): parsing required method"); - RequiredMethod(TypeMethod { - unsafety: style, - decl: d, - generics: generics, - abi: abi, - explicit_self: explicit_self, - }) + RequiredMethod(sig) } token::OpenDelim(token::Brace) => { debug!("parse_trait_methods(): parsing provided method"); let (inner_attrs, body) = p.parse_inner_attrs_and_block(); attrs.push_all(&inner_attrs[..]); - ProvidedMethod(ast::MethDecl(generics, - abi, - explicit_self, - style, - d, - body)) + ProvidedMethod(ast::MethDecl(sig, body)) } _ => { @@ -4758,13 +4753,13 @@ impl<'a> Parser<'a> { let body_span = body.span; let mut new_attrs = attrs; new_attrs.push_all(&inner_attrs[..]); - (ast::MethDecl(generics, - abi, - explicit_self, - unsafety, - decl, - body), - body_span.hi, new_attrs, ident) + (ast::MethDecl(ast::MethodSig { + generics: generics, + abi: abi, + explicit_self: explicit_self, + unsafety: unsafety, + decl: decl + }, body), body_span.hi, new_attrs, ident) } }; P(ImplItem { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a457355698d..20c8df42993 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -375,8 +375,9 @@ pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ide opt_explicit_self: Option<&ast::ExplicitSelf_>, generics: &ast::Generics) -> String { $to_string(|s| { - try!(s.print_fn(decl, Some(unsafety), abi::Rust, - name, generics, opt_explicit_self, ast::Inherited)); + try!(s.head("")); + try!(s.print_fn(decl, unsafety, abi::Rust, Some(name), + generics, opt_explicit_self, ast::Inherited)); try!(s.end()); // Close the head box s.end() // Close the outer box }) @@ -759,8 +760,10 @@ impl<'a> State<'a> { try!(self.print_outer_attributes(&item.attrs)); match item.node { ast::ForeignItemFn(ref decl, ref generics) => { - try!(self.print_fn(&**decl, None, abi::Rust, item.ident, generics, - None, item.vis)); + try!(self.head("")); + try!(self.print_fn(&**decl, ast::Unsafety::Normal, + abi::Rust, Some(item.ident), + generics, None, item.vis)); try!(self.end()); // end head-ibox try!(word(&mut self.s, ";")); self.end() // end the outer fn box @@ -861,11 +864,12 @@ impl<'a> State<'a> { try!(self.end()); // end the outer cbox } ast::ItemFn(ref decl, unsafety, abi, ref typarams, ref body) => { + try!(self.head("")); try!(self.print_fn( - &**decl, - Some(unsafety), + decl, + unsafety, abi, - item.ident, + Some(item.ident), typarams, None, item.vis @@ -1227,17 +1231,18 @@ impl<'a> State<'a> { } } - 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(ident), - &m.generics, - Some(&m.explicit_self.node))); - word(&mut self.s, ";") + pub fn print_method_sig(&mut self, + ident: ast::Ident, + m: &ast::MethodSig, + vis: ast::Visibility) + -> io::Result<()> { + self.print_fn(&m.decl, + m.unsafety, + m.abi, + Some(ident), + &m.generics, + Some(&m.explicit_self.node), + vis) } pub fn print_trait_item(&mut self, ti: &ast::TraitItem) @@ -1246,8 +1251,9 @@ impl<'a> State<'a> { 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::RequiredMethod(ref sig) => { + try!(self.print_method_sig(ti.ident, sig, ast::Inherited)); + word(&mut self.s, ";") } ast::ProvidedMethod(ref m) => { self.print_method(ti.ident, &ti.attrs, ast::Inherited, m) @@ -1280,20 +1286,10 @@ impl<'a> State<'a> { meth: &ast::Method) -> io::Result<()> { match *meth { - ast::MethDecl(ref generics, - abi, - ref explicit_self, - unsafety, - ref decl, - ref body) => { - try!(self.print_fn(&**decl, - Some(unsafety), - abi, - ident, - generics, - Some(&explicit_self.node), - vis)); - try!(word(&mut self.s, " ")); + ast::MethDecl(ref sig, ref body) => { + try!(self.head("")); + try!(self.print_method_sig(ident, sig, vis)); + try!(self.nbsp()); self.print_block_with_attrs(&**body, attrs) }, ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), @@ -2328,16 +2324,18 @@ impl<'a> State<'a> { pub fn print_fn(&mut self, decl: &ast::FnDecl, - unsafety: Option, + unsafety: ast::Unsafety, abi: abi::Abi, - name: ast::Ident, + name: Option, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>, vis: ast::Visibility) -> io::Result<()> { - try!(self.head("")); try!(self.print_fn_header_info(unsafety, abi, vis)); - try!(self.nbsp()); - try!(self.print_ident(name)); + + if let Some(name) = name { + try!(self.nbsp()); + try!(self.print_ident(name)); + } try!(self.print_generics(generics)); try!(self.print_fn_args_and_ret(decl, opt_explicit_self)); self.print_where_clause(generics) @@ -2704,25 +2702,14 @@ impl<'a> State<'a> { abi: abi::Abi, unsafety: ast::Unsafety, decl: &ast::FnDecl, - id: Option, + name: Option, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>) -> io::Result<()> { try!(self.ibox(indent_unit)); - try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited)); - - match id { - Some(id) => { - try!(word(&mut self.s, " ")); - try!(self.print_ident(id)); - } - _ => () - } - - try!(self.print_generics(generics)); - try!(zerobreak(&mut self.s)); - try!(self.print_fn_args_and_ret(decl, opt_explicit_self)); - try!(self.print_where_clause(generics)); + try!(self.print_fn(decl, unsafety, abi, name, + generics, opt_explicit_self, + ast::Inherited)); self.end() } @@ -2944,14 +2931,6 @@ impl<'a> State<'a> { } } - pub fn print_opt_unsafety(&mut self, - opt_unsafety: Option) -> io::Result<()> { - match opt_unsafety { - Some(unsafety) => self.print_unsafety(unsafety), - None => Ok(()) - } - } - pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi: Option) -> io::Result<()> { @@ -2977,11 +2956,11 @@ impl<'a> State<'a> { } pub fn print_fn_header_info(&mut self, - opt_unsafety: Option, + unsafety: ast::Unsafety, abi: abi::Abi, vis: ast::Visibility) -> io::Result<()> { try!(word(&mut self.s, &visibility_qualified(vis, ""))); - try!(self.print_opt_unsafety(opt_unsafety)); + try!(self.print_unsafety(unsafety)); if abi != abi::Rust { try!(self.word_nbsp("extern")); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 867f98f6077..4375e17ce0b 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -602,11 +602,11 @@ fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, method: &'v Method) { match *method { - MethDecl(_, _, _, _, ref decl, ref body) => { + MethDecl(ref sig, ref body) => { visitor.visit_ident(span, ident); visitor.visit_fn(FkMethod(ident, method), - &**decl, - &**body, + &sig.decl, + body, span, id); }, @@ -627,9 +627,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, } FkMethod(_, method) => { match *method { - MethDecl(ref generics, _, ref explicit_self, _, _, _) => { - visitor.visit_generics(generics); - visitor.visit_explicit_self(explicit_self); + MethDecl(ref sig, _) => { + visitor.visit_generics(&sig.generics); + visitor.visit_explicit_self(&sig.explicit_self); } MethMac(ref mac) => visitor.visit_mac(mac) } @@ -646,10 +646,10 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai 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); + RequiredMethod(ref sig) => { + visitor.visit_explicit_self(&sig.explicit_self); + visitor.visit_generics(&sig.generics); + walk_fn_decl(visitor, &sig.decl); } ProvidedMethod(ref method) => { walk_method_helper(visitor, diff --git a/src/test/compile-fail/impl-duplicate-methods.rs b/src/test/compile-fail/impl-duplicate-methods.rs index c0c951dd8b1..3b4def8c508 100644 --- a/src/test/compile-fail/impl-duplicate-methods.rs +++ b/src/test/compile-fail/impl-duplicate-methods.rs @@ -11,7 +11,7 @@ struct Foo; impl Foo { fn orange(&self){} - fn orange(&self){} //~ ERROR error: duplicate method in trait impl + fn orange(&self){} //~ ERROR error: duplicate method } fn main() {} diff --git a/src/test/compile-fail/issue-4265.rs b/src/test/compile-fail/issue-4265.rs index ab18e0bcddc..553436607d1 100644 --- a/src/test/compile-fail/issue-4265.rs +++ b/src/test/compile-fail/issue-4265.rs @@ -17,7 +17,7 @@ impl Foo { Foo { baz: 0 }.bar(); } - fn bar() { //~ ERROR duplicate method in trait impl + fn bar() { //~ ERROR duplicate method } }