@@ -438,6 +438,8 @@ pub(super) fn impl_method<'a, DB: HirDatabase>(
438
438
lookup
439
439
. new_types ( NewTypesKey :: ImplMethod )
440
440
. into_iter ( )
441
+ . filter ( |ty| !ty. type_arguments ( ) . any ( |it| it. contains_unknown ( ) ) )
442
+ . filter ( |_| should_continue ( ) )
441
443
. flat_map ( |ty| {
442
444
Impl :: all_for_type ( db, ty. clone ( ) ) . into_iter ( ) . map ( move |imp| ( ty. clone ( ) , imp) )
443
445
} )
@@ -450,22 +452,10 @@ pub(super) fn impl_method<'a, DB: HirDatabase>(
450
452
let fn_generics = GenericDef :: from ( it) ;
451
453
let imp_generics = GenericDef :: from ( imp) ;
452
454
453
- // Ignore const params for now
454
- let imp_type_params = imp_generics
455
- . type_or_const_params ( db)
456
- . into_iter ( )
457
- . map ( |it| it. as_type_param ( db) )
458
- . collect :: < Option < Vec < TypeParam > > > ( ) ?;
459
-
460
- // Ignore const params for now
461
- let fn_type_params = fn_generics
462
- . type_or_const_params ( db)
463
- . into_iter ( )
464
- . map ( |it| it. as_type_param ( db) )
465
- . collect :: < Option < Vec < TypeParam > > > ( ) ?;
466
-
467
455
// Ignore all functions that have something to do with lifetimes as we don't check them
468
- if !fn_generics. lifetime_params ( db) . is_empty ( ) {
456
+ if !fn_generics. lifetime_params ( db) . is_empty ( )
457
+ || !imp_generics. lifetime_params ( db) . is_empty ( )
458
+ {
469
459
return None ;
470
460
}
471
461
@@ -479,112 +469,59 @@ pub(super) fn impl_method<'a, DB: HirDatabase>(
479
469
return None ;
480
470
}
481
471
482
- // Only account for stable type parameters for now, unstable params can be default
483
- // tho, for example in `Box<T, #[unstable] A: Allocator>`
484
- if imp_type_params. iter ( ) . any ( |it| it. is_unstable ( db) && it. default ( db) . is_none ( ) )
485
- || fn_type_params. iter ( ) . any ( |it| it. is_unstable ( db) && it. default ( db) . is_none ( ) )
486
- {
472
+ // Ignore functions with generics for now as they kill the performance
473
+ // Also checking bounds for generics is problematic
474
+ if fn_generics. type_or_const_params ( db) . len ( ) > 0 {
487
475
return None ;
488
476
}
489
477
490
- // Double check that we have fully known type
491
- if ty. type_arguments ( ) . any ( |it| it. contains_unknown ( ) ) {
478
+ let ret_ty = it. ret_type_with_args ( db, ty. type_arguments ( ) ) ;
479
+ // Filter out functions that return references
480
+ if ctx. config . enable_borrowcheck && ret_ty. contains_reference ( db) || ret_ty. is_raw_ptr ( )
481
+ {
492
482
return None ;
493
483
}
494
484
495
- let non_default_fn_type_params_len =
496
- fn_type_params. iter ( ) . filter ( |it| it. default ( db) . is_none ( ) ) . count ( ) ;
497
-
498
- // Ignore functions with generics for now as they kill the performance
499
- // Also checking bounds for generics is problematic
500
- if non_default_fn_type_params_len > 0 {
485
+ // Ignore functions that do not change the type
486
+ if ty. could_unify_with_deeply ( db, & ret_ty) {
501
487
return None ;
502
488
}
503
489
504
- let generic_params = lookup
505
- . iter_types ( )
506
- . collect :: < Vec < _ > > ( ) // Force take ownership
507
- . into_iter ( )
508
- . permutations ( non_default_fn_type_params_len) ;
490
+ let self_ty =
491
+ it. self_param ( db) . expect ( "No self param" ) . ty_with_args ( db, ty. type_arguments ( ) ) ;
509
492
510
- let exprs: Vec < _ > = generic_params
511
- . filter ( |_| should_continue ( ) )
512
- . filter_map ( |generics| {
513
- // Insert default type params
514
- let mut g = generics. into_iter ( ) ;
515
- let generics: Vec < _ > = ty
516
- . type_arguments ( )
517
- . map ( Some )
518
- . chain ( fn_type_params. iter ( ) . map ( |it| match it. default ( db) {
519
- Some ( ty) => Some ( ty) ,
520
- None => {
521
- let generic = g. next ( ) . expect ( "Missing type param" ) ;
522
- // Filter out generics that do not unify due to trait bounds
523
- it. ty ( db) . could_unify_with ( db, & generic) . then_some ( generic)
524
- }
525
- } ) )
526
- . collect :: < Option < _ > > ( ) ?;
527
-
528
- let ret_ty = it. ret_type_with_args (
529
- db,
530
- ty. type_arguments ( ) . chain ( generics. iter ( ) . cloned ( ) ) ,
531
- ) ;
532
- // Filter out functions that return references
533
- if ctx. config . enable_borrowcheck && ret_ty. contains_reference ( db)
534
- || ret_ty. is_raw_ptr ( )
535
- {
536
- return None ;
537
- }
493
+ // Ignore functions that have different self type
494
+ if !self_ty. autoderef ( db) . any ( |s_ty| ty == s_ty) {
495
+ return None ;
496
+ }
538
497
539
- // Ignore functions that do not change the type
540
- if ty. could_unify_with_deeply ( db, & ret_ty) {
541
- return None ;
542
- }
498
+ let target_type_exprs = lookup. find ( db, & ty) . expect ( "Type not in lookup" ) ;
543
499
544
- let self_ty = it
545
- . self_param ( db)
546
- . expect ( "No self param" )
547
- . ty_with_args ( db, ty. type_arguments ( ) . chain ( generics. iter ( ) . cloned ( ) ) ) ;
500
+ // Early exit if some param cannot be filled from lookup
501
+ let param_exprs: Vec < Vec < Expr > > = it
502
+ . params_without_self_with_args ( db, ty. type_arguments ( ) )
503
+ . into_iter ( )
504
+ . map ( |field| lookup. find_autoref ( db, field. ty ( ) ) )
505
+ . collect :: < Option < _ > > ( ) ?;
548
506
549
- // Ignore functions that have different self type
550
- if !self_ty. autoderef ( db) . any ( |s_ty| ty == s_ty) {
551
- return None ;
507
+ let generics: Vec < _ > = ty. type_arguments ( ) . collect ( ) ;
508
+ let fn_exprs: Vec < Expr > = std:: iter:: once ( target_type_exprs)
509
+ . chain ( param_exprs)
510
+ . multi_cartesian_product ( )
511
+ . map ( |params| {
512
+ let mut params = params. into_iter ( ) ;
513
+ let target = Box :: new ( params. next ( ) . unwrap ( ) ) ;
514
+ Expr :: Method {
515
+ func : it,
516
+ generics : generics. clone ( ) ,
517
+ target,
518
+ params : params. collect ( ) ,
552
519
}
553
-
554
- let target_type_exprs = lookup. find ( db, & ty) . expect ( "Type not in lookup" ) ;
555
-
556
- // Early exit if some param cannot be filled from lookup
557
- let param_exprs: Vec < Vec < Expr > > = it
558
- . params_without_self_with_args (
559
- db,
560
- ty. type_arguments ( ) . chain ( generics. iter ( ) . cloned ( ) ) ,
561
- )
562
- . into_iter ( )
563
- . map ( |field| lookup. find_autoref ( db, field. ty ( ) ) )
564
- . collect :: < Option < _ > > ( ) ?;
565
-
566
- let fn_exprs: Vec < Expr > = std:: iter:: once ( target_type_exprs)
567
- . chain ( param_exprs)
568
- . multi_cartesian_product ( )
569
- . map ( |params| {
570
- let mut params = params. into_iter ( ) ;
571
- let target = Box :: new ( params. next ( ) . unwrap ( ) ) ;
572
- Expr :: Method {
573
- func : it,
574
- generics : generics. clone ( ) ,
575
- target,
576
- params : params. collect ( ) ,
577
- }
578
- } )
579
- . collect ( ) ;
580
-
581
- lookup. insert ( ret_ty. clone ( ) , fn_exprs. iter ( ) . cloned ( ) ) ;
582
- Some ( ( ret_ty, fn_exprs) )
583
520
} )
584
521
. collect ( ) ;
585
- Some ( exprs)
522
+
523
+ Some ( ( ret_ty, fn_exprs) )
586
524
} )
587
- . flatten ( )
588
525
. filter_map ( |( ty, exprs) | ty. could_unify_with_deeply ( db, & ctx. goal ) . then_some ( exprs) )
589
526
. flatten ( )
590
527
}
0 commit comments