8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- //! Give useful errors and suggestions to users when a method can't be
11
+ //! Give useful errors and suggestions to users when an item can't be
12
12
//! found or is otherwise invalid.
13
13
14
14
use CrateCtxt ;
@@ -27,12 +27,13 @@ use syntax::print::pprust;
27
27
use std:: cell;
28
28
use std:: cmp:: Ordering ;
29
29
30
- use super :: { MethodError , CandidateSource , impl_method, trait_method} ;
30
+ use super :: { MethodError , CandidateSource , impl_item, trait_item} ;
31
+ use super :: probe:: Mode ;
31
32
32
33
pub fn report_error < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
33
34
span : Span ,
34
35
rcvr_ty : Ty < ' tcx > ,
35
- method_name : ast:: Name ,
36
+ item_name : ast:: Name ,
36
37
rcvr_expr : Option < & ast:: Expr > ,
37
38
error : MethodError )
38
39
{
@@ -42,28 +43,30 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
42
43
}
43
44
44
45
match error {
45
- MethodError :: NoMatch ( static_sources, out_of_scope_traits) => {
46
+ MethodError :: NoMatch ( static_sources, out_of_scope_traits, mode ) => {
46
47
let cx = fcx. tcx ( ) ;
47
- let method_ustring = method_name . user_string ( cx) ;
48
+ let item_ustring = item_name . user_string ( cx) ;
48
49
49
50
fcx. type_error_message (
50
51
span,
51
52
|actual| {
52
- format ! ( "type `{}` does not implement any \
53
- method in scope named `{}`",
54
- actual,
55
- method_ustring)
53
+ format ! ( "no {} named `{}` found for type `{}` \
54
+ in the current scope",
55
+ if mode == Mode :: MethodCall { "method" }
56
+ else { "associated item" } ,
57
+ item_ustring,
58
+ actual)
56
59
} ,
57
60
rcvr_ty,
58
61
None ) ;
59
62
60
- // If the method has the name of a field, give a help note
63
+ // If the item has the name of a field, give a help note
61
64
if let ( & ty:: ty_struct( did, _) , Some ( _) ) = ( & rcvr_ty. sty , rcvr_expr) {
62
65
let fields = ty:: lookup_struct_fields ( cx, did) ;
63
- if fields. iter ( ) . any ( |f| f. name == method_name ) {
66
+ if fields. iter ( ) . any ( |f| f. name == item_name ) {
64
67
cx. sess . span_note ( span,
65
68
& format ! ( "use `(s.{0})(...)` if you meant to call the \
66
- function stored in the `{0}` field", method_ustring ) ) ;
69
+ function stored in the `{0}` field", item_ustring ) ) ;
67
70
}
68
71
}
69
72
@@ -72,25 +75,25 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
72
75
span,
73
76
"found defined static methods, maybe a `self` is missing?" ) ;
74
77
75
- report_candidates ( fcx, span, method_name , static_sources) ;
78
+ report_candidates ( fcx, span, item_name , static_sources) ;
76
79
}
77
80
78
- suggest_traits_to_import ( fcx, span, rcvr_ty, method_name ,
81
+ suggest_traits_to_import ( fcx, span, rcvr_ty, item_name ,
79
82
rcvr_expr, out_of_scope_traits)
80
83
}
81
84
82
85
MethodError :: Ambiguity ( sources) => {
83
86
span_err ! ( fcx. sess( ) , span, E0034 ,
84
- "multiple applicable methods in scope" ) ;
87
+ "multiple applicable items in scope" ) ;
85
88
86
- report_candidates ( fcx, span, method_name , sources) ;
89
+ report_candidates ( fcx, span, item_name , sources) ;
87
90
}
88
91
89
92
MethodError :: ClosureAmbiguity ( trait_def_id) => {
90
93
let msg = format ! ( "the `{}` method from the `{}` trait cannot be explicitly \
91
94
invoked on this closure as we have not yet inferred what \
92
95
kind of closure it is",
93
- method_name . user_string( fcx. tcx( ) ) ,
96
+ item_name . user_string( fcx. tcx( ) ) ,
94
97
ty:: item_path_str( fcx. tcx( ) , trait_def_id) ) ;
95
98
let msg = if let Some ( callee) = rcvr_expr {
96
99
format ! ( "{}; use overloaded call notation instead (e.g., `{}()`)" ,
@@ -104,19 +107,19 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
104
107
105
108
fn report_candidates ( fcx : & FnCtxt ,
106
109
span : Span ,
107
- method_name : ast:: Name ,
110
+ item_name : ast:: Name ,
108
111
mut sources : Vec < CandidateSource > ) {
109
112
sources. sort ( ) ;
110
113
sources. dedup ( ) ;
111
114
112
115
for ( idx, source) in sources. iter ( ) . enumerate ( ) {
113
116
match * source {
114
117
CandidateSource :: ImplSource ( impl_did) => {
115
- // Provide the best span we can. Use the method , if local to crate, else
116
- // the impl, if local to crate (method may be defaulted), else the call site.
117
- let method = impl_method ( fcx. tcx ( ) , impl_did, method_name ) . unwrap ( ) ;
118
+ // Provide the best span we can. Use the item , if local to crate, else
119
+ // the impl, if local to crate (item may be defaulted), else the call site.
120
+ let item = impl_item ( fcx. tcx ( ) , impl_did, item_name ) . unwrap ( ) ;
118
121
let impl_span = fcx. tcx ( ) . map . def_id_span ( impl_did, span) ;
119
- let method_span = fcx. tcx ( ) . map . def_id_span ( method . def_id , impl_span) ;
122
+ let item_span = fcx. tcx ( ) . map . def_id_span ( item . def_id ( ) , impl_span) ;
120
123
121
124
let impl_ty = check:: impl_self_ty ( fcx, span, impl_did) . ty ;
122
125
@@ -127,16 +130,16 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
127
130
trait_ref. def_id) ) ,
128
131
} ;
129
132
130
- span_note ! ( fcx. sess( ) , method_span ,
133
+ span_note ! ( fcx. sess( ) , item_span ,
131
134
"candidate #{} is defined in an impl{} for the type `{}`" ,
132
135
idx + 1 ,
133
136
insertion,
134
137
impl_ty. user_string( fcx. tcx( ) ) ) ;
135
138
}
136
139
CandidateSource :: TraitSource ( trait_did) => {
137
- let ( _, method ) = trait_method ( fcx. tcx ( ) , trait_did, method_name ) . unwrap ( ) ;
138
- let method_span = fcx. tcx ( ) . map . def_id_span ( method . def_id , span) ;
139
- span_note ! ( fcx. sess( ) , method_span ,
140
+ let ( _, item ) = trait_item ( fcx. tcx ( ) , trait_did, item_name ) . unwrap ( ) ;
141
+ let item_span = fcx. tcx ( ) . map . def_id_span ( item . def_id ( ) , span) ;
142
+ span_note ! ( fcx. sess( ) , item_span ,
140
143
"candidate #{} is defined in the trait `{}`" ,
141
144
idx + 1 ,
142
145
ty:: item_path_str( fcx. tcx( ) , trait_did) ) ;
@@ -152,19 +155,19 @@ pub type AllTraitsVec = Vec<TraitInfo>;
152
155
fn suggest_traits_to_import < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
153
156
span : Span ,
154
157
rcvr_ty : Ty < ' tcx > ,
155
- method_name : ast:: Name ,
158
+ item_name : ast:: Name ,
156
159
rcvr_expr : Option < & ast:: Expr > ,
157
160
valid_out_of_scope_traits : Vec < ast:: DefId > )
158
161
{
159
162
let tcx = fcx. tcx ( ) ;
160
- let method_ustring = method_name . user_string ( tcx) ;
163
+ let item_ustring = item_name . user_string ( tcx) ;
161
164
162
165
if !valid_out_of_scope_traits. is_empty ( ) {
163
166
let mut candidates = valid_out_of_scope_traits;
164
167
candidates. sort ( ) ;
165
168
candidates. dedup ( ) ;
166
169
let msg = format ! (
167
- "methods from traits can only be called if the trait is in scope; \
170
+ "items from traits can only be used if the trait is in scope; \
168
171
the following {traits_are} implemented but not in scope, \
169
172
perhaps add a `use` for {one_of_them}:",
170
173
traits_are = if candidates. len( ) == 1 { "trait is" } else { "traits are" } ,
@@ -185,7 +188,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
185
188
let type_is_local = type_derefs_to_local ( fcx, span, rcvr_ty, rcvr_expr) ;
186
189
187
190
// there's no implemented traits, so lets suggest some traits to
188
- // implement, by finding ones that have the method name, and are
191
+ // implement, by finding ones that have the item name, and are
189
192
// legal to implement.
190
193
let mut candidates = all_traits ( fcx. ccx )
191
194
. filter ( |info| {
@@ -196,7 +199,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
196
199
// implementing a trait would be legal but is rejected
197
200
// here).
198
201
( type_is_local || ast_util:: is_local ( info. def_id ) )
199
- && trait_method ( tcx, info. def_id , method_name ) . is_some ( )
202
+ && trait_item ( tcx, info. def_id , item_name ) . is_some ( )
200
203
} )
201
204
. collect :: < Vec < _ > > ( ) ;
202
205
@@ -209,12 +212,12 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
209
212
// of a type parameter: suggest adding a trait bound rather
210
213
// than implementing.
211
214
let msg = format ! (
212
- "methods from traits can only be called if the trait is implemented and in scope; \
213
- the following {traits_define} a method `{name}`, \
215
+ "items from traits can only be used if the trait is implemented and in scope; \
216
+ the following {traits_define} an item `{name}`, \
214
217
perhaps you need to implement {one_of_them}:",
215
218
traits_define = if candidates. len( ) == 1 { "trait defines" } else { "traits define" } ,
216
219
one_of_them = if candidates. len( ) == 1 { "it" } else { "one of them" } ,
217
- name = method_ustring ) ;
220
+ name = item_ustring ) ;
218
221
219
222
fcx. sess ( ) . fileline_help ( span, & msg[ ..] ) ;
220
223
0 commit comments