diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 05166fa6134..044ce87951b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -850,124 +850,75 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Check existing impl methods to see if they are both present in trait // and compatible with trait signature for impl_item in impl_items { + let ty_impl_item = ccx.tcx.impl_or_trait_item(local_def(impl_item.id)); + let ty_trait_item = trait_items.iter() + .find(|ac| ac.name() == ty_impl_item.name()) + .unwrap_or_else(|| { + // This is checked by resolve + tcx.sess.span_bug(impl_item.span, + &format!("impl-item `{}` is not a member of `{:?}`", + token::get_name(ty_impl_item.name()), + impl_trait_ref)); + }); match impl_item.node { ast::ConstImplItem(..) => { - let impl_const_def_id = local_def(impl_item.id); - let impl_const_ty = ccx.tcx.impl_or_trait_item(impl_const_def_id); + let impl_const = match ty_impl_item { + ty::ConstTraitItem(ref cti) => cti, + _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const") + }; // Find associated const definition. - let opt_associated_const = - trait_items.iter() - .find(|ac| ac.name() == impl_const_ty.name()); - match opt_associated_const { - Some(associated_const) => { - match (associated_const, &impl_const_ty) { - (&ty::ConstTraitItem(ref const_trait), - &ty::ConstTraitItem(ref const_impl)) => { - compare_const_impl(ccx.tcx, - &const_impl, - impl_item.span, - &const_trait, - &*impl_trait_ref); - } - _ => { - span_err!(tcx.sess, impl_item.span, E0323, - "item `{}` is an associated const, \ - which doesn't match its trait `{:?}`", - token::get_name(impl_const_ty.name()), - impl_trait_ref) - } - } - } - None => { - // This is `span_bug` as it should have already been - // caught in resolve. - tcx.sess.span_bug( - impl_item.span, - &format!( - "associated const `{}` is not a member of \ - trait `{:?}`", - token::get_name(impl_const_ty.name()), - impl_trait_ref)); - } + if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item { + compare_const_impl(ccx.tcx, + &impl_const, + impl_item.span, + trait_const, + &*impl_trait_ref); + } else { + span_err!(tcx.sess, impl_item.span, E0323, + "item `{}` is an associated const, \ + which doesn't match its trait `{:?}`", + token::get_name(impl_const.name), + impl_trait_ref) } } ast::MethodImplItem(ref sig, ref body) => { check_trait_fn_not_const(ccx, impl_item.span, sig.constness); - let impl_method_def_id = local_def(impl_item.id); - let impl_item_ty = ccx.tcx.impl_or_trait_item(impl_method_def_id); + let impl_method = match ty_impl_item { + ty::MethodTraitItem(ref mti) => mti, + _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method") + }; - // If this is an impl of a trait method, find the - // corresponding method definition in the trait. - let opt_trait_method_ty = - trait_items.iter() - .find(|ti| ti.name() == impl_item_ty.name()); - match opt_trait_method_ty { - Some(trait_method_ty) => { - match (trait_method_ty, &impl_item_ty) { - (&ty::MethodTraitItem(ref trait_method_ty), - &ty::MethodTraitItem(ref impl_method_ty)) => { - compare_impl_method(ccx.tcx, - &**impl_method_ty, - impl_item.span, - body.id, - &**trait_method_ty, - &*impl_trait_ref); - } - _ => { - span_err!(tcx.sess, impl_item.span, E0324, - "item `{}` is an associated method, \ - which doesn't match its trait `{:?}`", - token::get_name(impl_item_ty.name()), - impl_trait_ref) - } - } - } - None => { - // This is span_bug as it should have already been - // caught in resolve. - tcx.sess.span_bug( - impl_item.span, - &format!("method `{}` is not a member of trait `{:?}`", - token::get_name(impl_item_ty.name()), - impl_trait_ref)); - } + if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item { + compare_impl_method(ccx.tcx, + &impl_method, + impl_item.span, + body.id, + &trait_method, + &impl_trait_ref); + } else { + span_err!(tcx.sess, impl_item.span, E0324, + "item `{}` is an associated method, \ + which doesn't match its trait `{:?}`", + token::get_name(impl_method.name), + impl_trait_ref) } } ast::TypeImplItem(_) => { - let typedef_def_id = local_def(impl_item.id); - let typedef_ty = ccx.tcx.impl_or_trait_item(typedef_def_id); + let impl_type = match ty_impl_item { + ty::TypeTraitItem(ref tti) => tti, + _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type") + }; - // If this is an impl of an associated type, find the - // corresponding type definition in the trait. - let opt_associated_type = - trait_items.iter() - .find(|ti| ti.name() == typedef_ty.name()); - match opt_associated_type { - Some(associated_type) => { - match (associated_type, &typedef_ty) { - (&ty::TypeTraitItem(_), &ty::TypeTraitItem(_)) => {} - _ => { - span_err!(tcx.sess, impl_item.span, E0325, - "item `{}` is an associated type, \ - which doesn't match its trait `{:?}`", - token::get_name(typedef_ty.name()), - impl_trait_ref) - } - } - } - None => { - // This is `span_bug` as it should have already been - // caught in resolve. - tcx.sess.span_bug( - impl_item.span, - &format!( - "associated type `{}` is not a member of \ - trait `{:?}`", - token::get_name(typedef_ty.name()), - impl_trait_ref)); - } + if let &ty::TypeTraitItem(..) = ty_trait_item { + // ... + } else { + span_err!(tcx.sess, impl_item.span, E0325, + "item `{}` is an associated type, \ + which doesn't match its trait `{:?}`", + token::get_name(impl_type.name), + impl_trait_ref) } } ast::MacImplItem(_) => tcx.sess.span_bug(impl_item.span,