@@ -128,21 +128,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
128
128
}
129
129
130
130
match self . tcx . hir_node ( hir_id) {
131
- hir:: Node :: Expr ( & hir:: Expr {
132
- kind :
133
- hir:: ExprKind :: Call (
134
- hir:: Expr { kind : hir:: ExprKind :: Path ( qpath) , span : callee_span, .. } ,
135
- args,
136
- ) ,
137
- span,
138
- ..
139
- } ) => {
140
- if self . closure_span_overlaps_error ( error, span) {
141
- return false ;
131
+ hir:: Node :: Expr ( expr) => self . point_at_expr_if_possible (
132
+ error,
133
+ def_id,
134
+ expr,
135
+ predicate_self_type_to_point_at,
136
+ param_to_point_at,
137
+ fallback_param_to_point_at,
138
+ self_param_to_point_at,
139
+ ) ,
140
+
141
+ hir:: Node :: Ty ( hir:: Ty { kind : hir:: TyKind :: Path ( qpath) , .. } ) => {
142
+ for param in [
143
+ predicate_self_type_to_point_at,
144
+ param_to_point_at,
145
+ fallback_param_to_point_at,
146
+ self_param_to_point_at,
147
+ ]
148
+ . into_iter ( )
149
+ . flatten ( )
150
+ {
151
+ if self . point_at_path_if_possible ( error, def_id, param, & qpath) {
152
+ return true ;
153
+ }
142
154
}
143
155
156
+ false
157
+ }
158
+
159
+ _ => false ,
160
+ }
161
+ }
162
+
163
+ fn point_at_expr_if_possible (
164
+ & self ,
165
+ error : & mut traits:: FulfillmentError < ' tcx > ,
166
+ callee_def_id : DefId ,
167
+ expr : & ' tcx hir:: Expr < ' tcx > ,
168
+ predicate_self_type_to_point_at : Option < ty:: GenericArg < ' tcx > > ,
169
+ param_to_point_at : Option < ty:: GenericArg < ' tcx > > ,
170
+ fallback_param_to_point_at : Option < ty:: GenericArg < ' tcx > > ,
171
+ self_param_to_point_at : Option < ty:: GenericArg < ' tcx > > ,
172
+ ) -> bool {
173
+ if self . closure_span_overlaps_error ( error, expr. span ) {
174
+ return false ;
175
+ }
176
+
177
+ match expr. kind {
178
+ hir:: ExprKind :: Call (
179
+ hir:: Expr { kind : hir:: ExprKind :: Path ( qpath) , span : callee_span, .. } ,
180
+ args,
181
+ ) => {
144
182
if let Some ( param) = predicate_self_type_to_point_at
145
- && self . point_at_path_if_possible ( error, def_id , param, & qpath)
183
+ && self . point_at_path_if_possible ( error, callee_def_id , param, & qpath)
146
184
{
147
185
return true ;
148
186
}
@@ -153,9 +191,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
153
191
{
154
192
if self . blame_specific_arg_if_possible (
155
193
error,
156
- def_id ,
194
+ callee_def_id ,
157
195
param,
158
- hir_id,
196
+ expr . hir_id ,
159
197
* callee_span,
160
198
None ,
161
199
args,
@@ -168,88 +206,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
168
206
. into_iter ( )
169
207
. flatten ( )
170
208
{
171
- if self . point_at_path_if_possible ( error, def_id , param, & qpath) {
209
+ if self . point_at_path_if_possible ( error, callee_def_id , param, & qpath) {
172
210
return true ;
173
211
}
174
212
}
175
213
}
176
- hir:: Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: Path ( qpath) , span, .. } ) => {
177
- if self . closure_span_overlaps_error ( error, span) {
178
- return false ;
214
+ hir:: ExprKind :: Path ( qpath) => {
215
+ // If the parent is an call, then process this as a call.
216
+ //
217
+ // This is because the `WhereClauseInExpr` obligations come from
218
+ // the well-formedness of the *path* expression, but we care to
219
+ // point at the call expression (namely, its args).
220
+ if let hir:: Node :: Expr (
221
+ call_expr @ hir:: Expr { kind : hir:: ExprKind :: Call ( callee, ..) , .. } ,
222
+ ) = self . tcx . parent_hir_node ( expr. hir_id )
223
+ && callee. hir_id == expr. hir_id
224
+ {
225
+ return self . point_at_expr_if_possible (
226
+ error,
227
+ callee_def_id,
228
+ call_expr,
229
+ predicate_self_type_to_point_at,
230
+ param_to_point_at,
231
+ fallback_param_to_point_at,
232
+ self_param_to_point_at,
233
+ ) ;
179
234
}
180
235
236
+ // Otherwise, just try to point at path components.
237
+
181
238
if let Some ( param) = predicate_self_type_to_point_at
182
- && self . point_at_path_if_possible ( error, def_id , param, & qpath)
239
+ && self . point_at_path_if_possible ( error, callee_def_id , param, & qpath)
183
240
{
184
241
return true ;
185
242
}
186
243
187
- if let hir:: Node :: Expr ( hir:: Expr {
188
- kind : hir:: ExprKind :: Call ( callee, args) ,
189
- hir_id : call_hir_id,
190
- span : call_span,
191
- ..
192
- } ) = self . tcx . parent_hir_node ( hir_id)
193
- && callee. hir_id == hir_id
194
- {
195
- if self . closure_span_overlaps_error ( error, * call_span) {
196
- return false ;
197
- }
198
-
199
- for param in
200
- [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
201
- . into_iter ( )
202
- . flatten ( )
203
- {
204
- if self . blame_specific_arg_if_possible (
205
- error,
206
- def_id,
207
- param,
208
- * call_hir_id,
209
- callee. span ,
210
- None ,
211
- args,
212
- ) {
213
- return true ;
214
- }
215
- }
216
- }
217
-
218
244
for param in [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
219
245
. into_iter ( )
220
246
. flatten ( )
221
247
{
222
- if self . point_at_path_if_possible ( error, def_id , param, & qpath) {
248
+ if self . point_at_path_if_possible ( error, callee_def_id , param, & qpath) {
223
249
return true ;
224
250
}
225
251
}
226
252
}
227
- hir:: Node :: Ty ( hir:: Ty { kind : hir:: TyKind :: Path ( qpath) , .. } ) => {
228
- for param in [
229
- predicate_self_type_to_point_at,
230
- param_to_point_at,
231
- fallback_param_to_point_at,
232
- self_param_to_point_at,
233
- ]
234
- . into_iter ( )
235
- . flatten ( )
236
- {
237
- if self . point_at_path_if_possible ( error, def_id, param, & qpath) {
238
- return true ;
239
- }
240
- }
241
- }
242
- hir:: Node :: Expr ( & hir:: Expr {
243
- kind : hir:: ExprKind :: MethodCall ( segment, receiver, args, ..) ,
244
- span,
245
- ..
246
- } ) => {
247
- if self . closure_span_overlaps_error ( error, span) {
248
- return false ;
249
- }
250
-
253
+ hir:: ExprKind :: MethodCall ( segment, receiver, args, ..) => {
251
254
if let Some ( param) = predicate_self_type_to_point_at
252
- && self . point_at_generic_if_possible ( error, def_id , param, segment)
255
+ && self . point_at_generic_if_possible ( error, callee_def_id , param, segment)
253
256
{
254
257
// HACK: This is not correct, since `predicate_self_type_to_point_at` might
255
258
// not actually correspond to the receiver of the method call. But we
@@ -259,7 +262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
259
262
error. obligation . cause . map_code ( |parent_code| {
260
263
ObligationCauseCode :: FunctionArg {
261
264
arg_hir_id : receiver. hir_id ,
262
- call_hir_id : hir_id,
265
+ call_hir_id : expr . hir_id ,
263
266
parent_code,
264
267
}
265
268
} ) ;
@@ -272,9 +275,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
272
275
{
273
276
if self . blame_specific_arg_if_possible (
274
277
error,
275
- def_id ,
278
+ callee_def_id ,
276
279
param,
277
- hir_id,
280
+ expr . hir_id ,
278
281
segment. ident . span ,
279
282
Some ( receiver) ,
280
283
args,
@@ -283,7 +286,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
283
286
}
284
287
}
285
288
if let Some ( param_to_point_at) = param_to_point_at
286
- && self . point_at_generic_if_possible ( error, def_id, param_to_point_at, segment)
289
+ && self . point_at_generic_if_possible (
290
+ error,
291
+ callee_def_id,
292
+ param_to_point_at,
293
+ segment,
294
+ )
287
295
{
288
296
return true ;
289
297
}
@@ -297,25 +305,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
297
305
return true ;
298
306
}
299
307
}
300
- hir:: Node :: Expr ( & hir:: Expr {
301
- kind : hir:: ExprKind :: Struct ( qpath, fields, ..) ,
302
- span,
303
- ..
304
- } ) => {
305
- if self . closure_span_overlaps_error ( error, span) {
306
- return false ;
307
- }
308
-
308
+ hir:: ExprKind :: Struct ( qpath, fields, ..) => {
309
309
if let Res :: Def ( DefKind :: Struct | DefKind :: Variant , variant_def_id) =
310
- self . typeck_results . borrow ( ) . qpath_res ( qpath, hir_id)
310
+ self . typeck_results . borrow ( ) . qpath_res ( qpath, expr . hir_id )
311
311
{
312
312
for param in
313
313
[ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
314
314
. into_iter ( )
315
315
. flatten ( )
316
316
{
317
- let refined_expr =
318
- self . point_at_field_if_possible ( def_id, param, variant_def_id, fields) ;
317
+ let refined_expr = self . point_at_field_if_possible (
318
+ callee_def_id,
319
+ param,
320
+ variant_def_id,
321
+ fields,
322
+ ) ;
319
323
320
324
match refined_expr {
321
325
None => { }
@@ -339,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
339
343
. into_iter ( )
340
344
. flatten ( )
341
345
{
342
- if self . point_at_path_if_possible ( error, def_id , param, qpath) {
346
+ if self . point_at_path_if_possible ( error, callee_def_id , param, qpath) {
343
347
return true ;
344
348
}
345
349
}
0 commit comments