12
12
13
13
use astconv:: AstConv ;
14
14
use check:: { FnCtxt } ;
15
- use check:: { impl_self_ty} ;
16
15
use check:: vtable;
17
16
use check:: vtable:: select_new_fcx_obligations;
18
17
use middle:: subst;
19
18
use middle:: traits;
20
19
use middle:: ty:: * ;
21
20
use middle:: ty;
22
21
use middle:: infer;
23
- use util:: ppaux:: { Repr , UserString } ;
22
+ use util:: ppaux:: Repr ;
24
23
25
24
use std:: rc:: Rc ;
26
25
use syntax:: ast:: { DefId } ;
@@ -30,14 +29,18 @@ use syntax::codemap::Span;
30
29
pub use self :: MethodError :: * ;
31
30
pub use self :: CandidateSource :: * ;
32
31
32
+ pub use self :: suggest:: { report_error, AllTraitsVec } ;
33
+
33
34
mod confirm;
34
35
mod doc;
35
36
mod probe;
37
+ mod suggest;
36
38
37
39
pub enum MethodError {
38
40
// 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 > ) ,
41
44
42
45
// Multiple methods might apply.
43
46
Ambiguity ( Vec < CandidateSource > ) ,
@@ -63,7 +66,7 @@ pub fn exists<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
63
66
{
64
67
match probe:: probe ( fcx, span, method_name, self_ty, call_expr_id) {
65
68
Ok ( _) => true ,
66
- Err ( NoMatch ( _) ) => false ,
69
+ Err ( NoMatch ( _, _ ) ) => false ,
67
70
Err ( Ambiguity ( _) ) => true ,
68
71
}
69
72
}
@@ -294,105 +297,6 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
294
297
Some ( callee)
295
298
}
296
299
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
- }
396
300
397
301
/// Find method with name `method_name` defined in `trait_def_id` and return it, along with its
398
302
/// index (or `None`, if no such method).
0 commit comments