about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-06-30 18:25:06 +0300
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-07-04 14:08:09 +0300
commitace86701a949bd9d0a7b2e9b6f43de52e99ccc35 (patch)
tree788b904953a31d38d25a65648ea66c30bc52c47f /src
parent0dc08240ea755679e3daec3832a04b22a8fc90bf (diff)
downloadrust-ace86701a949bd9d0a7b2e9b6f43de52e99ccc35.tar.gz
rust-ace86701a949bd9d0a7b2e9b6f43de52e99ccc35.zip
Clean-up check_impl_items_against_trait
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/mod.rs163
1 files changed, 57 insertions, 106 deletions
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);
-
-                // 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));
-                    }
+                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 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);
-
-                // 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));
-                    }
+                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 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,