@@ -579,7 +579,7 @@ impl InferenceContext<'_> {
579
579
}
580
580
ty
581
581
}
582
- Expr :: Field { expr, name } => self . infer_field_access ( tgt_expr, * expr, name) ,
582
+ Expr :: Field { expr, name } => self . infer_field_access ( tgt_expr, * expr, name, expected ) ,
583
583
Expr :: Await { expr } => {
584
584
let inner_ty = self . infer_expr_inner ( * expr, & Expectation :: none ( ) ) ;
585
585
self . resolve_associated_type ( inner_ty, self . resolve_future_future_output ( ) )
@@ -1456,7 +1456,13 @@ impl InferenceContext<'_> {
1456
1456
} )
1457
1457
}
1458
1458
1459
- fn infer_field_access ( & mut self , tgt_expr : ExprId , receiver : ExprId , name : & Name ) -> Ty {
1459
+ fn infer_field_access (
1460
+ & mut self ,
1461
+ tgt_expr : ExprId ,
1462
+ receiver : ExprId ,
1463
+ name : & Name ,
1464
+ expected : & Expectation ,
1465
+ ) -> Ty {
1460
1466
let receiver_ty = self . infer_expr_inner ( receiver, & Expectation :: none ( ) ) ;
1461
1467
1462
1468
if name. is_missing ( ) {
@@ -1482,28 +1488,42 @@ impl InferenceContext<'_> {
1482
1488
ty
1483
1489
}
1484
1490
None => {
1485
- // no field found,
1486
- let method_with_same_name_exists = {
1487
- self . get_traits_in_scope ( ) ;
1488
-
1489
- let canonicalized_receiver = self . canonicalize ( receiver_ty. clone ( ) ) ;
1490
- method_resolution:: lookup_method (
1491
- self . db ,
1492
- & canonicalized_receiver. value ,
1493
- self . table . trait_env . clone ( ) ,
1494
- self . get_traits_in_scope ( ) . as_ref ( ) . left_or_else ( |& it| it) ,
1495
- VisibleFromModule :: Filter ( self . resolver . module ( ) ) ,
1496
- name,
1497
- )
1498
- . is_some ( )
1499
- } ;
1491
+ // no field found, lets attempt to resolve it like a function so that IDE things
1492
+ // work out while people are typing
1493
+ let canonicalized_receiver = self . canonicalize ( receiver_ty. clone ( ) ) ;
1494
+ let resolved = method_resolution:: lookup_method (
1495
+ self . db ,
1496
+ & canonicalized_receiver. value ,
1497
+ self . table . trait_env . clone ( ) ,
1498
+ self . get_traits_in_scope ( ) . as_ref ( ) . left_or_else ( |& it| it) ,
1499
+ VisibleFromModule :: Filter ( self . resolver . module ( ) ) ,
1500
+ name,
1501
+ ) ;
1500
1502
self . result . diagnostics . push ( InferenceDiagnostic :: UnresolvedField {
1501
1503
expr : tgt_expr,
1502
- receiver : receiver_ty,
1504
+ receiver : receiver_ty. clone ( ) ,
1503
1505
name : name. clone ( ) ,
1504
- method_with_same_name_exists,
1506
+ method_with_same_name_exists : resolved . is_some ( ) ,
1505
1507
} ) ;
1506
- self . err_ty ( )
1508
+ match resolved {
1509
+ Some ( ( adjust, func, _) ) => {
1510
+ let ( ty, adjustments) = adjust. apply ( & mut self . table , receiver_ty) ;
1511
+ let generics = generics ( self . db . upcast ( ) , func. into ( ) ) ;
1512
+ let substs = self . substs_for_method_call ( generics, None ) ;
1513
+ self . write_expr_adj ( receiver, adjustments) ;
1514
+ self . write_method_resolution ( tgt_expr, func, substs. clone ( ) ) ;
1515
+
1516
+ self . check_method_call (
1517
+ tgt_expr,
1518
+ & [ ] ,
1519
+ self . db . value_ty ( func. into ( ) ) ,
1520
+ substs,
1521
+ ty,
1522
+ expected,
1523
+ )
1524
+ }
1525
+ None => self . err_ty ( ) ,
1526
+ }
1507
1527
}
1508
1528
}
1509
1529
}
@@ -1517,7 +1537,7 @@ impl InferenceContext<'_> {
1517
1537
generic_args : Option < & GenericArgs > ,
1518
1538
expected : & Expectation ,
1519
1539
) -> Ty {
1520
- let receiver_ty = self . infer_expr ( receiver, & Expectation :: none ( ) ) ;
1540
+ let receiver_ty = self . infer_expr_inner ( receiver, & Expectation :: none ( ) ) ;
1521
1541
let canonicalized_receiver = self . canonicalize ( receiver_ty. clone ( ) ) ;
1522
1542
1523
1543
let resolved = method_resolution:: lookup_method (
@@ -1568,23 +1588,32 @@ impl InferenceContext<'_> {
1568
1588
)
1569
1589
}
1570
1590
} ;
1591
+ self . check_method_call ( tgt_expr, args, method_ty, substs, receiver_ty, expected)
1592
+ }
1593
+
1594
+ fn check_method_call (
1595
+ & mut self ,
1596
+ tgt_expr : ExprId ,
1597
+ args : & [ ExprId ] ,
1598
+ method_ty : Binders < Ty > ,
1599
+ substs : Substitution ,
1600
+ receiver_ty : Ty ,
1601
+ expected : & Expectation ,
1602
+ ) -> Ty {
1571
1603
let method_ty = method_ty. substitute ( Interner , & substs) ;
1572
1604
self . register_obligations_for_call ( & method_ty) ;
1573
- let ( formal_receiver_ty, param_tys, ret_ty, is_varargs) =
1605
+ let ( ( formal_receiver_ty, param_tys) , ret_ty, is_varargs) =
1574
1606
match method_ty. callable_sig ( self . db ) {
1575
- Some ( sig) => {
1607
+ Some ( sig) => (
1576
1608
if !sig. params ( ) . is_empty ( ) {
1577
- (
1578
- sig. params ( ) [ 0 ] . clone ( ) ,
1579
- sig. params ( ) [ 1 ..] . to_vec ( ) ,
1580
- sig. ret ( ) . clone ( ) ,
1581
- sig. is_varargs ,
1582
- )
1609
+ ( sig. params ( ) [ 0 ] . clone ( ) , sig. params ( ) [ 1 ..] . to_vec ( ) )
1583
1610
} else {
1584
- ( self . err_ty ( ) , Vec :: new ( ) , sig. ret ( ) . clone ( ) , sig. is_varargs )
1585
- }
1586
- }
1587
- None => ( self . err_ty ( ) , Vec :: new ( ) , self . err_ty ( ) , true ) ,
1611
+ ( self . err_ty ( ) , Vec :: new ( ) )
1612
+ } ,
1613
+ sig. ret ( ) . clone ( ) ,
1614
+ sig. is_varargs ,
1615
+ ) ,
1616
+ None => ( ( self . err_ty ( ) , Vec :: new ( ) ) , self . err_ty ( ) , true ) ,
1588
1617
} ;
1589
1618
self . unify ( & formal_receiver_ty, & receiver_ty) ;
1590
1619
0 commit comments