@@ -294,143 +294,151 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
294
294
let id = map. get_parent_item ( hir_id) ;
295
295
let hir_id: hir:: HirId = id. into ( ) ;
296
296
297
- if let Some ( node) = map. find ( hir_id) && let Some ( body_id) = node. body_id ( ) {
298
- let body = map. body ( body_id) ;
299
- expr_finder. visit_expr ( body. value ) ;
300
- let mut eraser = TypeEraser { tcx } ;
301
- let mut prev = eraser. fold_ty ( ty) ;
302
- let mut prev_span = None ;
303
-
304
- for binding in expr_finder. uses {
305
- // In every expression where the binding is referenced, we will look at that
306
- // expression's type and see if it is where the incorrect found type was fully
307
- // "materialized" and point at it. We will also try to provide a suggestion there.
308
- let parent = map. get_parent_node ( binding. hir_id ) ;
309
- if let Some ( hir:: Node :: Expr ( expr) )
310
- | Some ( hir:: Node :: Stmt ( hir:: Stmt {
311
- kind : hir:: StmtKind :: Expr ( expr) | hir:: StmtKind :: Semi ( expr) ,
312
- ..
313
- } ) ) = & map. find ( parent)
314
- && let hir:: ExprKind :: MethodCall ( s, rcvr, args, _span) = expr. kind
315
- && rcvr. hir_id == binding. hir_id
316
- && let Some ( def_id) = self . typeck_results . borrow ( ) . type_dependent_def_id ( expr. hir_id )
317
- {
318
- // We special case methods, because they can influence inference through the
319
- // call's arguments and we can provide a more explicit span.
320
- let sig = self . tcx . fn_sig ( def_id) ;
321
- let def_self_ty = sig. input ( 0 ) . skip_binder ( ) ;
322
- let rcvr_ty = self . node_ty ( rcvr. hir_id ) ;
323
- // Get the evaluated type *after* calling the method call, so that the influence
324
- // of the arguments can be reflected in the receiver type. The receiver
325
- // expression has the type *before* theis analysis is done.
326
- let ty = match self . lookup_probe ( s. ident , rcvr_ty, expr, probe:: ProbeScope :: TraitsInScope ) {
327
- Ok ( pick) => pick. self_ty ,
328
- Err ( _) => rcvr_ty,
329
- } ;
330
- // Remove one layer of references to account for `&mut self` and
331
- // `&self`, so that we can compare it against the binding.
332
- let ( ty, def_self_ty) = match ( ty. kind ( ) , def_self_ty. kind ( ) ) {
333
- ( ty:: Ref ( _, ty, a) , ty:: Ref ( _, self_ty, b) ) if a == b => ( * ty, * self_ty) ,
334
- _ => ( ty, def_self_ty) ,
335
- } ;
336
- let mut param_args = FxHashMap :: default ( ) ;
337
- let mut param_expected = FxHashMap :: default ( ) ;
338
- let mut param_found = FxHashMap :: default ( ) ;
339
- if self . can_eq ( self . param_env , ty, found) . is_ok ( ) {
340
- // We only point at the first place where the found type was inferred.
341
- for ( i, param_ty) in sig. inputs ( ) . skip_binder ( ) . iter ( ) . skip ( 1 ) . enumerate ( ) {
342
- if def_self_ty. contains ( * param_ty) && let ty:: Param ( _) = param_ty. kind ( ) {
343
- // We found an argument that references a type parameter in `Self`,
344
- // so we assume that this is the argument that caused the found
345
- // type, which we know already because of `can_eq` above was first
346
- // inferred in this method call.
347
- let arg = & args[ i] ;
348
- let arg_ty = self . node_ty ( arg. hir_id ) ;
349
- err. span_label (
350
- arg. span ,
351
- & format ! (
352
- "this is of type `{arg_ty}`, which makes `{ident}` to be \
353
- inferred as `{ty}`",
354
- ) ,
355
- ) ;
356
- param_args. insert ( param_ty, ( arg, arg_ty) ) ;
357
- }
297
+ let Some ( node) = map. find ( hir_id) else { return false ; } ;
298
+ let Some ( body_id) = node. body_id ( ) else { return false ; } ;
299
+ let body = map. body ( body_id) ;
300
+ expr_finder. visit_expr ( body. value ) ;
301
+ let mut eraser = TypeEraser { tcx } ;
302
+ let mut prev = eraser. fold_ty ( ty) ;
303
+ let mut prev_span = None ;
304
+
305
+ for binding in expr_finder. uses {
306
+ // In every expression where the binding is referenced, we will look at that
307
+ // expression's type and see if it is where the incorrect found type was fully
308
+ // "materialized" and point at it. We will also try to provide a suggestion there.
309
+ let parent = map. get_parent_node ( binding. hir_id ) ;
310
+ if let Some ( hir:: Node :: Expr ( expr) )
311
+ | Some ( hir:: Node :: Stmt ( hir:: Stmt {
312
+ kind : hir:: StmtKind :: Expr ( expr) | hir:: StmtKind :: Semi ( expr) ,
313
+ ..
314
+ } ) ) = & map. find ( parent)
315
+ && let hir:: ExprKind :: MethodCall ( segment, rcvr, args, _span) = expr. kind
316
+ && rcvr. hir_id == binding. hir_id
317
+ && let Some ( def_id) = self . typeck_results . borrow ( ) . type_dependent_def_id ( expr. hir_id )
318
+ {
319
+ // We special case methods, because they can influence inference through the
320
+ // call's arguments and we can provide a more explicit span.
321
+ let sig = self . tcx . fn_sig ( def_id) ;
322
+ let def_self_ty = sig. input ( 0 ) . skip_binder ( ) ;
323
+ let rcvr_ty = self . node_ty ( rcvr. hir_id ) ;
324
+ // Get the evaluated type *after* calling the method call, so that the influence
325
+ // of the arguments can be reflected in the receiver type. The receiver
326
+ // expression has the type *before* theis analysis is done.
327
+ let ty = match self . lookup_probe (
328
+ segment. ident ,
329
+ rcvr_ty,
330
+ expr,
331
+ probe:: ProbeScope :: TraitsInScope ,
332
+ ) {
333
+ Ok ( pick) => pick. self_ty ,
334
+ Err ( _) => rcvr_ty,
335
+ } ;
336
+ // Remove one layer of references to account for `&mut self` and
337
+ // `&self`, so that we can compare it against the binding.
338
+ let ( ty, def_self_ty) = match ( ty. kind ( ) , def_self_ty. kind ( ) ) {
339
+ ( ty:: Ref ( _, ty, a) , ty:: Ref ( _, self_ty, b) ) if a == b => ( * ty, * self_ty) ,
340
+ _ => ( ty, def_self_ty) ,
341
+ } ;
342
+ let mut param_args = FxHashMap :: default ( ) ;
343
+ let mut param_expected = FxHashMap :: default ( ) ;
344
+ let mut param_found = FxHashMap :: default ( ) ;
345
+ if self . can_eq ( self . param_env , ty, found) . is_ok ( ) {
346
+ // We only point at the first place where the found type was inferred.
347
+ for ( i, param_ty) in sig. inputs ( ) . skip_binder ( ) . iter ( ) . skip ( 1 ) . enumerate ( ) {
348
+ if def_self_ty. contains ( * param_ty) && let ty:: Param ( _) = param_ty. kind ( ) {
349
+ // We found an argument that references a type parameter in `Self`,
350
+ // so we assume that this is the argument that caused the found
351
+ // type, which we know already because of `can_eq` above was first
352
+ // inferred in this method call.
353
+ let arg = & args[ i] ;
354
+ let arg_ty = self . node_ty ( arg. hir_id ) ;
355
+ err. span_label (
356
+ arg. span ,
357
+ & format ! (
358
+ "this is of type `{arg_ty}`, which makes `{ident}` to be \
359
+ inferred as `{ty}`",
360
+ ) ,
361
+ ) ;
362
+ param_args. insert ( param_ty, ( arg, arg_ty) ) ;
358
363
}
359
364
}
365
+ }
360
366
361
- // Here we find, for a type param `T`, the type that `T` is in the current
362
- // method call *and* in the original expected type. That way, we can see if we
363
- // can give any structured suggestion for the function argument.
364
- let mut c = CollectAllMismatches {
365
- infcx : & self . infcx ,
366
- param_env : self . param_env ,
367
- errors : vec ! [ ] ,
368
- } ;
369
- let _ = c. relate ( def_self_ty, ty) ;
370
- for error in c. errors {
371
- if let TypeError :: Sorts ( error) = error {
372
- param_found. insert ( error. expected , error. found ) ;
373
- }
374
- }
375
- c. errors = vec ! [ ] ;
376
- let _ = c. relate ( def_self_ty, expected) ;
377
- for error in c. errors {
378
- if let TypeError :: Sorts ( error) = error {
379
- param_expected. insert ( error. expected , error. found ) ;
380
- }
367
+ // Here we find, for a type param `T`, the type that `T` is in the current
368
+ // method call *and* in the original expected type. That way, we can see if we
369
+ // can give any structured suggestion for the function argument.
370
+ let mut c = CollectAllMismatches {
371
+ infcx : & self . infcx ,
372
+ param_env : self . param_env ,
373
+ errors : vec ! [ ] ,
374
+ } ;
375
+ let _ = c. relate ( def_self_ty, ty) ;
376
+ for error in c. errors {
377
+ if let TypeError :: Sorts ( error) = error {
378
+ param_found. insert ( error. expected , error. found ) ;
381
379
}
382
- for ( param, ( arg, arg_ty) ) in param_args. iter ( ) {
383
- let Some ( expected) = param_expected. get ( param) else { continue ; } ;
384
- let Some ( found) = param_found. get ( param) else { continue ; } ;
385
- if self . can_eq ( self . param_env , * arg_ty, * found) . is_err ( ) { continue ; }
386
- self . suggest_deref_ref_or_into ( err, arg, * expected, * found, None ) ;
380
+ }
381
+ c. errors = vec ! [ ] ;
382
+ let _ = c. relate ( def_self_ty, expected) ;
383
+ for error in c. errors {
384
+ if let TypeError :: Sorts ( error) = error {
385
+ param_expected. insert ( error. expected , error. found ) ;
387
386
}
387
+ }
388
+ for ( param, ( arg, arg_ty) ) in param_args. iter ( ) {
389
+ let Some ( expected) = param_expected. get ( param) else { continue ; } ;
390
+ let Some ( found) = param_found. get ( param) else { continue ; } ;
391
+ if self . can_eq ( self . param_env , * arg_ty, * found) . is_err ( ) { continue ; }
392
+ self . suggest_deref_ref_or_into ( err, arg, * expected, * found, None ) ;
393
+ }
388
394
389
- let ty = eraser. fold_ty ( ty) ;
390
- if ty. references_error ( ) {
391
- break ;
392
- }
393
- if ty != prev
394
- && param_args. is_empty ( )
395
- && self . can_eq ( self . param_env , ty, found) . is_ok ( )
396
- {
397
- // We only point at the first place where the found type was inferred.
398
- err. span_label (
399
- s. ident . span ,
400
- with_forced_trimmed_paths ! ( format!(
401
- "here the type of `{ident}` is inferred to be `{ty}`" ,
402
- ) ) ,
403
- ) ;
404
- break ;
405
- }
406
- prev = ty;
407
- } else {
408
- let ty = eraser. fold_ty ( self . node_ty ( binding. hir_id ) ) ;
409
- if ty. references_error ( ) {
410
- break ;
411
- }
412
- if ty != prev && let Some ( span) = prev_span && self . can_eq ( self . param_env , ty, found) . is_ok ( ) {
413
- // We only point at the first place where the found type was inferred.
414
- // We use the *previous* span because if the type is known *here* it means
415
- // it was *evaluated earlier*. We don't do this for method calls because we
416
- // evaluate the method's self type eagerly, but not in any other case.
417
- err. span_label (
418
- span,
419
- with_forced_trimmed_paths ! ( format!(
420
- "here the type of `{ident}` is inferred to be `{ty}`" ,
421
- ) ) ,
422
- ) ;
423
- break ;
424
- }
425
- prev = ty;
395
+ let ty = eraser. fold_ty ( ty) ;
396
+ if ty. references_error ( ) {
397
+ break ;
426
398
}
427
- if binding. hir_id == expr. hir_id {
428
- // Do not look at expressions that come after the expression we were originally
429
- // evaluating and had a type error.
399
+ if ty != prev
400
+ && param_args. is_empty ( )
401
+ && self . can_eq ( self . param_env , ty, found) . is_ok ( )
402
+ {
403
+ // We only point at the first place where the found type was inferred.
404
+ err. span_label (
405
+ segment. ident . span ,
406
+ with_forced_trimmed_paths ! ( format!(
407
+ "here the type of `{ident}` is inferred to be `{ty}`" ,
408
+ ) ) ,
409
+ ) ;
430
410
break ;
431
411
}
432
- prev_span = Some ( binding. span ) ;
412
+ prev = ty;
413
+ } else {
414
+ let ty = eraser. fold_ty ( self . node_ty ( binding. hir_id ) ) ;
415
+ if ty. references_error ( ) {
416
+ break ;
417
+ }
418
+ if ty != prev
419
+ && let Some ( span) = prev_span
420
+ && self . can_eq ( self . param_env , ty, found) . is_ok ( )
421
+ {
422
+ // We only point at the first place where the found type was inferred.
423
+ // We use the *previous* span because if the type is known *here* it means
424
+ // it was *evaluated earlier*. We don't do this for method calls because we
425
+ // evaluate the method's self type eagerly, but not in any other case.
426
+ err. span_label (
427
+ span,
428
+ with_forced_trimmed_paths ! ( format!(
429
+ "here the type of `{ident}` is inferred to be `{ty}`" ,
430
+ ) ) ,
431
+ ) ;
432
+ break ;
433
+ }
434
+ prev = ty;
435
+ }
436
+ if binding. hir_id == expr. hir_id {
437
+ // Do not look at expressions that come after the expression we were originally
438
+ // evaluating and had a type error.
439
+ break ;
433
440
}
441
+ prev_span = Some ( binding. span ) ;
434
442
}
435
443
true
436
444
}
0 commit comments