about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2015-01-13 17:05:04 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2015-01-13 17:05:04 +1100
commitaf506fa5d15b892c2fa6df442e106e1afcb7abca (patch)
tree54fb90d44f37b8fedb8a202e60c602e6e9fc0fe8 /src
parent3d5fbae33897a8340542f21b6ded913148ca9199 (diff)
downloadrust-af506fa5d15b892c2fa6df442e106e1afcb7abca.tar.gz
rust-af506fa5d15b892c2fa6df442e106e1afcb7abca.zip
typeck: move method errors/suggestions to their own file.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/method/mod.rs105
-rw-r--r--src/librustc_typeck/check/method/suggest.rs122
2 files changed, 126 insertions, 101 deletions
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 0c53a16a811..8637a915305 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -12,7 +12,6 @@
 
 use astconv::AstConv;
 use check::{FnCtxt};
-use check::{impl_self_ty};
 use check::vtable;
 use check::vtable::select_new_fcx_obligations;
 use middle::subst;
@@ -20,7 +19,7 @@ use middle::traits;
 use middle::ty::*;
 use middle::ty;
 use middle::infer;
-use util::ppaux::{Repr, UserString};
+use util::ppaux::Repr;
 
 use std::rc::Rc;
 use syntax::ast::{DefId};
@@ -30,9 +29,12 @@ use syntax::codemap::Span;
 pub use self::MethodError::*;
 pub use self::CandidateSource::*;
 
+pub use self::suggest::report_error;
+
 mod confirm;
 mod doc;
 mod probe;
+mod suggest;
 
 pub enum MethodError {
     // Did not find an applicable method, but we did find various
@@ -294,105 +296,6 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     Some(callee)
 }
 
-pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                              span: Span,
-                              rcvr_ty: Ty<'tcx>,
-                              method_name: ast::Name,
-                              error: MethodError)
-{
-    match error {
-        NoMatch(static_sources) => {
-            let cx = fcx.tcx();
-            let method_ustring = method_name.user_string(cx);
-
-            // True if the type is a struct and contains a field with
-            // the same name as the not-found method
-            let is_field = match rcvr_ty.sty {
-                ty_struct(did, _) =>
-                    ty::lookup_struct_fields(cx, did)
-                        .iter()
-                        .any(|f| f.name.user_string(cx) == method_ustring),
-                _ => false
-            };
-
-            fcx.type_error_message(
-                span,
-                |actual| {
-                    format!("type `{}` does not implement any \
-                             method in scope named `{}`",
-                            actual,
-                            method_ustring)
-                },
-                rcvr_ty,
-                None);
-
-            // If the method has the name of a field, give a help note
-            if is_field {
-                cx.sess.span_note(span,
-                    &format!("use `(s.{0})(...)` if you meant to call the \
-                            function stored in the `{0}` field", method_ustring)[]);
-            }
-
-            if static_sources.len() > 0 {
-                fcx.tcx().sess.fileline_note(
-                    span,
-                    "found defined static methods, maybe a `self` is missing?");
-
-                report_candidates(fcx, span, method_name, static_sources);
-            }
-        }
-
-        Ambiguity(sources) => {
-            span_err!(fcx.sess(), span, E0034,
-                      "multiple applicable methods in scope");
-
-            report_candidates(fcx, span, method_name, sources);
-        }
-    }
-
-    fn report_candidates(fcx: &FnCtxt,
-                         span: Span,
-                         method_name: ast::Name,
-                         mut sources: Vec<CandidateSource>) {
-        sources.sort();
-        sources.dedup();
-
-        for (idx, source) in sources.iter().enumerate() {
-            match *source {
-                ImplSource(impl_did) => {
-                    // Provide the best span we can. Use the method, if local to crate, else
-                    // the impl, if local to crate (method may be defaulted), else the call site.
-                    let method = impl_method(fcx.tcx(), impl_did, method_name).unwrap();
-                    let impl_span = fcx.tcx().map.def_id_span(impl_did, span);
-                    let method_span = fcx.tcx().map.def_id_span(method.def_id, impl_span);
-
-                    let impl_ty = impl_self_ty(fcx, span, impl_did).ty;
-
-                    let insertion = match impl_trait_ref(fcx.tcx(), impl_did) {
-                        None => format!(""),
-                        Some(trait_ref) => format!(" of the trait `{}`",
-                                                   ty::item_path_str(fcx.tcx(),
-                                                                     trait_ref.def_id)),
-                    };
-
-                    span_note!(fcx.sess(), method_span,
-                               "candidate #{} is defined in an impl{} for the type `{}`",
-                               idx + 1u,
-                               insertion,
-                               impl_ty.user_string(fcx.tcx()));
-                }
-                TraitSource(trait_did) => {
-                    let (_, method) = trait_method(fcx.tcx(), trait_did, method_name).unwrap();
-                    let method_span = fcx.tcx().map.def_id_span(method.def_id, span);
-                    span_note!(fcx.sess(), method_span,
-                               "candidate #{} is defined in the trait `{}`",
-                               idx + 1u,
-                               ty::item_path_str(fcx.tcx(), trait_did));
-                }
-            }
-        }
-    }
-}
 
 /// Find method with name `method_name` defined in `trait_def_id` and return it, along with its
 /// index (or `None`, if no such method).
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
new file mode 100644
index 00000000000..b6d97d2df9d
--- /dev/null
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -0,0 +1,122 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Give useful errors and suggestions to users when a method can't be
+//! found or is otherwise invalid.
+
+use astconv::AstConv;
+use check::{self, FnCtxt};
+use middle::ty::{self, Ty};
+use util::ppaux::UserString;
+
+use syntax::ast;
+use syntax::codemap::Span;
+
+use super::{MethodError, CandidateSource, impl_method, trait_method};
+
+pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                              span: Span,
+                              rcvr_ty: Ty<'tcx>,
+                              method_name: ast::Name,
+                              error: MethodError)
+{
+    match error {
+        MethodError::NoMatch(static_sources) => {
+            let cx = fcx.tcx();
+            let method_ustring = method_name.user_string(cx);
+
+            // True if the type is a struct and contains a field with
+            // the same name as the not-found method
+            let is_field = match rcvr_ty.sty {
+                ty::ty_struct(did, _) =>
+                    ty::lookup_struct_fields(cx, did)
+                        .iter()
+                        .any(|f| f.name.user_string(cx) == method_ustring),
+                _ => false
+            };
+
+            fcx.type_error_message(
+                span,
+                |actual| {
+                    format!("type `{}` does not implement any \
+                             method in scope named `{}`",
+                            actual,
+                            method_ustring)
+                },
+                rcvr_ty,
+                None);
+
+            // If the method has the name of a field, give a help note
+            if is_field {
+                cx.sess.span_note(span,
+                    &format!("use `(s.{0})(...)` if you meant to call the \
+                            function stored in the `{0}` field", method_ustring)[]);
+            }
+
+            if static_sources.len() > 0 {
+                fcx.tcx().sess.fileline_note(
+                    span,
+                    "found defined static methods, maybe a `self` is missing?");
+
+                report_candidates(fcx, span, method_name, static_sources);
+            }
+        }
+
+        MethodError::Ambiguity(sources) => {
+            span_err!(fcx.sess(), span, E0034,
+                      "multiple applicable methods in scope");
+
+            report_candidates(fcx, span, method_name, sources);
+        }
+    }
+
+    fn report_candidates(fcx: &FnCtxt,
+                         span: Span,
+                         method_name: ast::Name,
+                         mut sources: Vec<CandidateSource>) {
+        sources.sort();
+        sources.dedup();
+
+        for (idx, source) in sources.iter().enumerate() {
+            match *source {
+                CandidateSource::ImplSource(impl_did) => {
+                    // Provide the best span we can. Use the method, if local to crate, else
+                    // the impl, if local to crate (method may be defaulted), else the call site.
+                    let method = impl_method(fcx.tcx(), impl_did, method_name).unwrap();
+                    let impl_span = fcx.tcx().map.def_id_span(impl_did, span);
+                    let method_span = fcx.tcx().map.def_id_span(method.def_id, impl_span);
+
+                    let impl_ty = check::impl_self_ty(fcx, span, impl_did).ty;
+
+                    let insertion = match ty::impl_trait_ref(fcx.tcx(), impl_did) {
+                        None => format!(""),
+                        Some(trait_ref) => format!(" of the trait `{}`",
+                                                   ty::item_path_str(fcx.tcx(),
+                                                                     trait_ref.def_id)),
+                    };
+
+                    span_note!(fcx.sess(), method_span,
+                               "candidate #{} is defined in an impl{} for the type `{}`",
+                               idx + 1u,
+                               insertion,
+                               impl_ty.user_string(fcx.tcx()));
+                }
+                CandidateSource::TraitSource(trait_did) => {
+                    let (_, method) = trait_method(fcx.tcx(), trait_did, method_name).unwrap();
+                    let method_span = fcx.tcx().map.def_id_span(method.def_id, span);
+                    span_note!(fcx.sess(), method_span,
+                               "candidate #{} is defined in the trait `{}`",
+                               idx + 1u,
+                               ty::item_path_str(fcx.tcx(), trait_did));
+                }
+            }
+        }
+    }
+}