Clean-up check_impl_items_against_trait

This commit is contained in:
Ariel Ben-Yehuda 2015-06-30 18:25:06 +03:00
parent 0dc08240ea
commit ace86701a9

View file

@ -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,