1212
1313use astconv:: AstConv ;
1414use check:: { FnCtxt } ;
15- use check:: { impl_self_ty} ;
1615use check:: vtable;
1716use check:: vtable:: select_new_fcx_obligations;
1817use middle:: subst;
1918use middle:: traits;
2019use middle:: ty:: * ;
2120use middle:: ty;
2221use middle:: infer;
23- use util:: ppaux:: { Repr , UserString } ;
22+ use util:: ppaux:: Repr ;
2423
2524use std:: rc:: Rc ;
2625use syntax:: ast:: { DefId } ;
@@ -30,14 +29,18 @@ use syntax::codemap::Span;
3029pub use self :: MethodError :: * ;
3130pub use self :: CandidateSource :: * ;
3231
32+ pub use self :: suggest:: { report_error, AllTraitsVec } ;
33+
3334mod confirm;
3435mod doc;
3536mod probe;
37+ mod suggest;
3638
3739pub enum MethodError {
3840 // Did not find an applicable method, but we did find various
39- // static methods that may apply.
40- NoMatch ( Vec < CandidateSource > ) ,
41+ // static methods that may apply, as well as a list of
42+ // not-in-scope traits which may work.
43+ NoMatch ( Vec < CandidateSource > , Vec < ast:: DefId > ) ,
4144
4245 // Multiple methods might apply.
4346 Ambiguity ( Vec < CandidateSource > ) ,
@@ -63,7 +66,7 @@ pub fn exists<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
6366{
6467 match probe:: probe ( fcx, span, method_name, self_ty, call_expr_id) {
6568 Ok ( _) => true ,
66- Err ( NoMatch ( _) ) => false ,
69+ Err ( NoMatch ( _, _ ) ) => false ,
6770 Err ( Ambiguity ( _) ) => true ,
6871 }
6972}
@@ -294,105 +297,6 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
294297 Some ( callee)
295298}
296299
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 + 1 u,
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 + 1 u,
390- ty:: item_path_str( fcx. tcx( ) , trait_did) ) ;
391- }
392- }
393- }
394- }
395- }
396300
397301/// Find method with name `method_name` defined in `trait_def_id` and return it, along with its
398302/// index (or `None`, if no such method).
0 commit comments