@@ -1167,10 +1167,13 @@ fn iterate_trait_method_candidates(
1167
1167
// trait, but if we find out it doesn't, we'll skip the rest of the
1168
1168
// iteration
1169
1169
let mut known_implemented = false ;
1170
- for & ( _, item) in data. items . iter ( ) {
1170
+ ' items: for & ( _, item) in data. items . iter ( ) {
1171
+ if let AssocItemId :: TypeAliasId ( _) = item {
1172
+ continue ' items;
1173
+ }
1171
1174
// Don't pass a `visible_from_module` down to `is_valid_candidate`,
1172
1175
// since only inherent methods should be included into visibility checking.
1173
- let visible = match is_valid_candidate ( table, name, receiver_ty, item, self_ty, None ) {
1176
+ let visible = match is_valid_method_candidate ( table, name, receiver_ty, item, self_ty) {
1174
1177
IsValidCandidate :: Yes => true ,
1175
1178
IsValidCandidate :: NotVisible => false ,
1176
1179
IsValidCandidate :: No => continue ,
@@ -1414,6 +1417,75 @@ fn is_valid_candidate(
1414
1417
}
1415
1418
}
1416
1419
1420
+ /// Checks whether a given `AssocItemId` is applicable for `receiver_ty`.
1421
+ ///
1422
+ /// This method should *only* be called by [`iterate_trait_method_candidates`],
1423
+ /// as it is responsible for determining applicability in completions.
1424
+ #[ tracing:: instrument( skip_all, fields( name) ) ]
1425
+ fn is_valid_method_candidate (
1426
+ table : & mut InferenceTable < ' _ > ,
1427
+ name : Option < & Name > ,
1428
+ receiver_ty : Option < & Ty > ,
1429
+ item : AssocItemId ,
1430
+ self_ty : & Ty ,
1431
+ ) -> IsValidCandidate {
1432
+ let db = table. db ;
1433
+ match item {
1434
+ AssocItemId :: FunctionId ( fn_id) => {
1435
+ let db = table. db ;
1436
+ let data = db. function_data ( fn_id) ;
1437
+
1438
+ check_that ! ( name. map_or( true , |n| n == & data. name) ) ;
1439
+
1440
+ table. run_in_snapshot ( |table| {
1441
+ let container = fn_id. lookup ( db. upcast ( ) ) . container ;
1442
+ let ( impl_subst, expect_self_ty) = match container {
1443
+ ItemContainerId :: ImplId ( it) => {
1444
+ let subst = TyBuilder :: subst_for_def ( db, it, None )
1445
+ . fill_with_inference_vars ( table)
1446
+ . build ( ) ;
1447
+ let self_ty = db. impl_self_ty ( it) . substitute ( Interner , & subst) ;
1448
+ ( subst, self_ty)
1449
+ }
1450
+ ItemContainerId :: TraitId ( it) => {
1451
+ let subst = TyBuilder :: subst_for_def ( db, it, None )
1452
+ . fill_with_inference_vars ( table)
1453
+ . build ( ) ;
1454
+ let self_ty = subst. at ( Interner , 0 ) . assert_ty_ref ( Interner ) . clone ( ) ;
1455
+ ( subst, self_ty)
1456
+ }
1457
+ _ => unreachable ! ( ) ,
1458
+ } ;
1459
+
1460
+ check_that ! ( table. unify( & expect_self_ty, self_ty) ) ;
1461
+
1462
+ if let Some ( receiver_ty) = receiver_ty {
1463
+ check_that ! ( data. has_self_param( ) ) ;
1464
+
1465
+ let fn_subst = TyBuilder :: subst_for_def ( db, fn_id, Some ( impl_subst. clone ( ) ) )
1466
+ . fill_with_inference_vars ( table)
1467
+ . build ( ) ;
1468
+
1469
+ let sig = db. callable_item_signature ( fn_id. into ( ) ) ;
1470
+ let expected_receiver =
1471
+ sig. map ( |s| s. params ( ) [ 0 ] . clone ( ) ) . substitute ( Interner , & fn_subst) ;
1472
+
1473
+ check_that ! ( table. unify( receiver_ty, & expected_receiver) ) ;
1474
+ }
1475
+
1476
+ IsValidCandidate :: Yes
1477
+ } )
1478
+ }
1479
+ AssocItemId :: ConstId ( c) => {
1480
+ check_that ! ( receiver_ty. is_none( ) ) ;
1481
+ check_that ! ( name. map_or( true , |n| db. const_data( c) . name. as_ref( ) == Some ( n) ) ) ;
1482
+
1483
+ IsValidCandidate :: Yes
1484
+ }
1485
+ _ => IsValidCandidate :: No ,
1486
+ }
1487
+ }
1488
+
1417
1489
enum IsValidCandidate {
1418
1490
Yes ,
1419
1491
No ,
@@ -1441,6 +1513,8 @@ fn is_valid_fn_candidate(
1441
1513
}
1442
1514
table. run_in_snapshot ( |table| {
1443
1515
let container = fn_id. lookup ( db. upcast ( ) ) . container ;
1516
+
1517
+ let _p = tracing:: span!( tracing:: Level :: INFO , "subst_for_def" ) . entered ( ) ;
1444
1518
let ( impl_subst, expect_self_ty) = match container {
1445
1519
ItemContainerId :: ImplId ( it) => {
1446
1520
let subst =
@@ -1459,6 +1533,7 @@ fn is_valid_fn_candidate(
1459
1533
1460
1534
check_that ! ( table. unify( & expect_self_ty, self_ty) ) ;
1461
1535
1536
+ let _p = tracing:: span!( tracing:: Level :: INFO , "check_receiver_ty" ) . entered ( ) ;
1462
1537
if let Some ( receiver_ty) = receiver_ty {
1463
1538
check_that ! ( data. has_self_param( ) ) ;
1464
1539
@@ -1473,6 +1548,7 @@ fn is_valid_fn_candidate(
1473
1548
check_that ! ( table. unify( receiver_ty, & expected_receiver) ) ;
1474
1549
}
1475
1550
1551
+ let _p = tracing:: span!( tracing:: Level :: INFO , "check_item_container" ) . entered ( ) ;
1476
1552
if let ItemContainerId :: ImplId ( impl_id) = container {
1477
1553
// We need to consider the bounds on the impl to distinguish functions of the same name
1478
1554
// for a type.
0 commit comments