@@ -128,21 +128,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
128128 }
129129
130130 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+ }
142154 }
143155
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+ ) => {
144182 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)
146184 {
147185 return true ;
148186 }
@@ -153,9 +191,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
153191 {
154192 if self . blame_specific_arg_if_possible (
155193 error,
156- def_id ,
194+ callee_def_id ,
157195 param,
158- hir_id,
196+ expr . hir_id ,
159197 * callee_span,
160198 None ,
161199 args,
@@ -168,88 +206,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
168206 . into_iter ( )
169207 . flatten ( )
170208 {
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) {
172210 return true ;
173211 }
174212 }
175213 }
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+ ) ;
179234 }
180235
236+ // Otherwise, just try to point at path components.
237+
181238 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)
183240 {
184241 return true ;
185242 }
186243
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-
218244 for param in [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
219245 . into_iter ( )
220246 . flatten ( )
221247 {
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) {
223249 return true ;
224250 }
225251 }
226252 }
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, ..) => {
251254 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)
253256 {
254257 // HACK: This is not correct, since `predicate_self_type_to_point_at` might
255258 // not actually correspond to the receiver of the method call. But we
@@ -259,7 +262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
259262 error. obligation . cause . map_code ( |parent_code| {
260263 ObligationCauseCode :: FunctionArg {
261264 arg_hir_id : receiver. hir_id ,
262- call_hir_id : hir_id,
265+ call_hir_id : expr . hir_id ,
263266 parent_code,
264267 }
265268 } ) ;
@@ -272,9 +275,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
272275 {
273276 if self . blame_specific_arg_if_possible (
274277 error,
275- def_id ,
278+ callee_def_id ,
276279 param,
277- hir_id,
280+ expr . hir_id ,
278281 segment. ident . span ,
279282 Some ( receiver) ,
280283 args,
@@ -283,7 +286,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
283286 }
284287 }
285288 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+ )
287295 {
288296 return true ;
289297 }
@@ -297,25 +305,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
297305 return true ;
298306 }
299307 }
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, ..) => {
309309 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 )
311311 {
312312 for param in
313313 [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
314314 . into_iter ( )
315315 . flatten ( )
316316 {
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+ ) ;
319323
320324 match refined_expr {
321325 None => { }
@@ -339,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
339343 . into_iter ( )
340344 . flatten ( )
341345 {
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) {
343347 return true ;
344348 }
345349 }
0 commit comments