Skip to content

Commit af506fa

Browse files
committed
typeck: move method errors/suggestions to their own file.
1 parent 3d5fbae commit af506fa

File tree

2 files changed

+126
-101
lines changed

2 files changed

+126
-101
lines changed

src/librustc_typeck/check/method/mod.rs

+4-101
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@
1212
1313
use astconv::AstConv;
1414
use check::{FnCtxt};
15-
use check::{impl_self_ty};
1615
use check::vtable;
1716
use check::vtable::select_new_fcx_obligations;
1817
use middle::subst;
1918
use middle::traits;
2019
use middle::ty::*;
2120
use middle::ty;
2221
use middle::infer;
23-
use util::ppaux::{Repr, UserString};
22+
use util::ppaux::Repr;
2423

2524
use std::rc::Rc;
2625
use syntax::ast::{DefId};
@@ -30,9 +29,12 @@ use syntax::codemap::Span;
3029
pub use self::MethodError::*;
3130
pub use self::CandidateSource::*;
3231

32+
pub use self::suggest::report_error;
33+
3334
mod confirm;
3435
mod doc;
3536
mod probe;
37+
mod suggest;
3638

3739
pub enum MethodError {
3840
// 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>,
294296
Some(callee)
295297
}
296298

297-
pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
298-
span: Span,
299-
rcvr_ty: Ty<'tcx>,
300-
method_name: ast::Name,
301-
error: MethodError)
302-
{
303-
match error {
304-
NoMatch(static_sources) => {
305-
let cx = fcx.tcx();
306-
let method_ustring = method_name.user_string(cx);
307-
308-
// True if the type is a struct and contains a field with
309-
// the same name as the not-found method
310-
let is_field = match rcvr_ty.sty {
311-
ty_struct(did, _) =>
312-
ty::lookup_struct_fields(cx, did)
313-
.iter()
314-
.any(|f| f.name.user_string(cx) == method_ustring),
315-
_ => false
316-
};
317-
318-
fcx.type_error_message(
319-
span,
320-
|actual| {
321-
format!("type `{}` does not implement any \
322-
method in scope named `{}`",
323-
actual,
324-
method_ustring)
325-
},
326-
rcvr_ty,
327-
None);
328-
329-
// If the method has the name of a field, give a help note
330-
if is_field {
331-
cx.sess.span_note(span,
332-
&format!("use `(s.{0})(...)` if you meant to call the \
333-
function stored in the `{0}` field", method_ustring)[]);
334-
}
335-
336-
if static_sources.len() > 0 {
337-
fcx.tcx().sess.fileline_note(
338-
span,
339-
"found defined static methods, maybe a `self` is missing?");
340-
341-
report_candidates(fcx, span, method_name, static_sources);
342-
}
343-
}
344-
345-
Ambiguity(sources) => {
346-
span_err!(fcx.sess(), span, E0034,
347-
"multiple applicable methods in scope");
348-
349-
report_candidates(fcx, span, method_name, sources);
350-
}
351-
}
352-
353-
fn report_candidates(fcx: &FnCtxt,
354-
span: Span,
355-
method_name: ast::Name,
356-
mut sources: Vec<CandidateSource>) {
357-
sources.sort();
358-
sources.dedup();
359-
360-
for (idx, source) in sources.iter().enumerate() {
361-
match *source {
362-
ImplSource(impl_did) => {
363-
// Provide the best span we can. Use the method, if local to crate, else
364-
// the impl, if local to crate (method may be defaulted), else the call site.
365-
let method = impl_method(fcx.tcx(), impl_did, method_name).unwrap();
366-
let impl_span = fcx.tcx().map.def_id_span(impl_did, span);
367-
let method_span = fcx.tcx().map.def_id_span(method.def_id, impl_span);
368-
369-
let impl_ty = impl_self_ty(fcx, span, impl_did).ty;
370-
371-
let insertion = match impl_trait_ref(fcx.tcx(), impl_did) {
372-
None => format!(""),
373-
Some(trait_ref) => format!(" of the trait `{}`",
374-
ty::item_path_str(fcx.tcx(),
375-
trait_ref.def_id)),
376-
};
377-
378-
span_note!(fcx.sess(), method_span,
379-
"candidate #{} is defined in an impl{} for the type `{}`",
380-
idx + 1u,
381-
insertion,
382-
impl_ty.user_string(fcx.tcx()));
383-
}
384-
TraitSource(trait_did) => {
385-
let (_, method) = trait_method(fcx.tcx(), trait_did, method_name).unwrap();
386-
let method_span = fcx.tcx().map.def_id_span(method.def_id, span);
387-
span_note!(fcx.sess(), method_span,
388-
"candidate #{} is defined in the trait `{}`",
389-
idx + 1u,
390-
ty::item_path_str(fcx.tcx(), trait_did));
391-
}
392-
}
393-
}
394-
}
395-
}
396299

397300
/// Find method with name `method_name` defined in `trait_def_id` and return it, along with its
398301
/// index (or `None`, if no such method).
+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Give useful errors and suggestions to users when a method can't be
12+
//! found or is otherwise invalid.
13+
14+
use astconv::AstConv;
15+
use check::{self, FnCtxt};
16+
use middle::ty::{self, Ty};
17+
use util::ppaux::UserString;
18+
19+
use syntax::ast;
20+
use syntax::codemap::Span;
21+
22+
use super::{MethodError, CandidateSource, impl_method, trait_method};
23+
24+
pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
25+
span: Span,
26+
rcvr_ty: Ty<'tcx>,
27+
method_name: ast::Name,
28+
error: MethodError)
29+
{
30+
match error {
31+
MethodError::NoMatch(static_sources) => {
32+
let cx = fcx.tcx();
33+
let method_ustring = method_name.user_string(cx);
34+
35+
// True if the type is a struct and contains a field with
36+
// the same name as the not-found method
37+
let is_field = match rcvr_ty.sty {
38+
ty::ty_struct(did, _) =>
39+
ty::lookup_struct_fields(cx, did)
40+
.iter()
41+
.any(|f| f.name.user_string(cx) == method_ustring),
42+
_ => false
43+
};
44+
45+
fcx.type_error_message(
46+
span,
47+
|actual| {
48+
format!("type `{}` does not implement any \
49+
method in scope named `{}`",
50+
actual,
51+
method_ustring)
52+
},
53+
rcvr_ty,
54+
None);
55+
56+
// If the method has the name of a field, give a help note
57+
if is_field {
58+
cx.sess.span_note(span,
59+
&format!("use `(s.{0})(...)` if you meant to call the \
60+
function stored in the `{0}` field", method_ustring)[]);
61+
}
62+
63+
if static_sources.len() > 0 {
64+
fcx.tcx().sess.fileline_note(
65+
span,
66+
"found defined static methods, maybe a `self` is missing?");
67+
68+
report_candidates(fcx, span, method_name, static_sources);
69+
}
70+
}
71+
72+
MethodError::Ambiguity(sources) => {
73+
span_err!(fcx.sess(), span, E0034,
74+
"multiple applicable methods in scope");
75+
76+
report_candidates(fcx, span, method_name, sources);
77+
}
78+
}
79+
80+
fn report_candidates(fcx: &FnCtxt,
81+
span: Span,
82+
method_name: ast::Name,
83+
mut sources: Vec<CandidateSource>) {
84+
sources.sort();
85+
sources.dedup();
86+
87+
for (idx, source) in sources.iter().enumerate() {
88+
match *source {
89+
CandidateSource::ImplSource(impl_did) => {
90+
// Provide the best span we can. Use the method, if local to crate, else
91+
// the impl, if local to crate (method may be defaulted), else the call site.
92+
let method = impl_method(fcx.tcx(), impl_did, method_name).unwrap();
93+
let impl_span = fcx.tcx().map.def_id_span(impl_did, span);
94+
let method_span = fcx.tcx().map.def_id_span(method.def_id, impl_span);
95+
96+
let impl_ty = check::impl_self_ty(fcx, span, impl_did).ty;
97+
98+
let insertion = match ty::impl_trait_ref(fcx.tcx(), impl_did) {
99+
None => format!(""),
100+
Some(trait_ref) => format!(" of the trait `{}`",
101+
ty::item_path_str(fcx.tcx(),
102+
trait_ref.def_id)),
103+
};
104+
105+
span_note!(fcx.sess(), method_span,
106+
"candidate #{} is defined in an impl{} for the type `{}`",
107+
idx + 1u,
108+
insertion,
109+
impl_ty.user_string(fcx.tcx()));
110+
}
111+
CandidateSource::TraitSource(trait_did) => {
112+
let (_, method) = trait_method(fcx.tcx(), trait_did, method_name).unwrap();
113+
let method_span = fcx.tcx().map.def_id_span(method.def_id, span);
114+
span_note!(fcx.sess(), method_span,
115+
"candidate #{} is defined in the trait `{}`",
116+
idx + 1u,
117+
ty::item_path_str(fcx.tcx(), trait_did));
118+
}
119+
}
120+
}
121+
}
122+
}

0 commit comments

Comments
 (0)