16
16
pub ( crate ) mod cast;
17
17
pub ( crate ) mod closure;
18
18
mod coerce;
19
- mod diagnostics;
19
+ pub ( crate ) mod diagnostics;
20
20
mod expr;
21
21
mod mutability;
22
22
mod pat;
@@ -1480,21 +1480,22 @@ impl<'a> InferenceContext<'a> {
1480
1480
& self . diagnostics ,
1481
1481
InferenceTyDiagnosticSource :: Body ,
1482
1482
) ;
1483
+ let mut path_ctx = ctx. at_path ( path, node) ;
1483
1484
let ( resolution, unresolved) = if value_ns {
1484
- let Some ( res) = ctx . resolve_path_in_value_ns ( path , node , HygieneId :: ROOT ) else {
1485
+ let Some ( res) = path_ctx . resolve_path_in_value_ns ( HygieneId :: ROOT ) else {
1485
1486
return ( self . err_ty ( ) , None ) ;
1486
1487
} ;
1487
1488
match res {
1488
1489
ResolveValueResult :: ValueNs ( value, _) => match value {
1489
1490
ValueNs :: EnumVariantId ( var) => {
1490
- let substs = ctx . substs_from_path ( path , var. into ( ) , true ) ;
1491
+ let substs = path_ctx . substs_from_path ( var. into ( ) , true ) ;
1491
1492
drop ( ctx) ;
1492
1493
let ty = self . db . ty ( var. lookup ( self . db . upcast ( ) ) . parent . into ( ) ) ;
1493
1494
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
1494
1495
return ( ty, Some ( var. into ( ) ) ) ;
1495
1496
}
1496
1497
ValueNs :: StructId ( strukt) => {
1497
- let substs = ctx . substs_from_path ( path , strukt. into ( ) , true ) ;
1498
+ let substs = path_ctx . substs_from_path ( strukt. into ( ) , true ) ;
1498
1499
drop ( ctx) ;
1499
1500
let ty = self . db . ty ( strukt. into ( ) ) ;
1500
1501
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
@@ -1509,7 +1510,7 @@ impl<'a> InferenceContext<'a> {
1509
1510
ResolveValueResult :: Partial ( typens, unresolved, _) => ( typens, Some ( unresolved) ) ,
1510
1511
}
1511
1512
} else {
1512
- match ctx . resolve_path_in_type_ns ( path , node ) {
1513
+ match path_ctx . resolve_path_in_type_ns ( ) {
1513
1514
Some ( ( it, idx) ) => ( it, idx) ,
1514
1515
None => return ( self . err_ty ( ) , None ) ,
1515
1516
}
@@ -1520,21 +1521,21 @@ impl<'a> InferenceContext<'a> {
1520
1521
} ;
1521
1522
return match resolution {
1522
1523
TypeNs :: AdtId ( AdtId :: StructId ( strukt) ) => {
1523
- let substs = ctx . substs_from_path ( path , strukt. into ( ) , true ) ;
1524
+ let substs = path_ctx . substs_from_path ( strukt. into ( ) , true ) ;
1524
1525
drop ( ctx) ;
1525
1526
let ty = self . db . ty ( strukt. into ( ) ) ;
1526
1527
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
1527
1528
forbid_unresolved_segments ( ( ty, Some ( strukt. into ( ) ) ) , unresolved)
1528
1529
}
1529
1530
TypeNs :: AdtId ( AdtId :: UnionId ( u) ) => {
1530
- let substs = ctx . substs_from_path ( path , u. into ( ) , true ) ;
1531
+ let substs = path_ctx . substs_from_path ( u. into ( ) , true ) ;
1531
1532
drop ( ctx) ;
1532
1533
let ty = self . db . ty ( u. into ( ) ) ;
1533
1534
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
1534
1535
forbid_unresolved_segments ( ( ty, Some ( u. into ( ) ) ) , unresolved)
1535
1536
}
1536
1537
TypeNs :: EnumVariantId ( var) => {
1537
- let substs = ctx . substs_from_path ( path , var. into ( ) , true ) ;
1538
+ let substs = path_ctx . substs_from_path ( var. into ( ) , true ) ;
1538
1539
drop ( ctx) ;
1539
1540
let ty = self . db . ty ( var. lookup ( self . db . upcast ( ) ) . parent . into ( ) ) ;
1540
1541
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
@@ -1545,31 +1546,32 @@ impl<'a> InferenceContext<'a> {
1545
1546
let substs = generics. placeholder_subst ( self . db ) ;
1546
1547
let mut ty = self . db . impl_self_ty ( impl_id) . substitute ( Interner , & substs) ;
1547
1548
1548
- let Some ( mut remaining_idx) = unresolved else {
1549
+ let Some ( remaining_idx) = unresolved else {
1549
1550
drop ( ctx) ;
1550
1551
return self . resolve_variant_on_alias ( ty, None , mod_path) ;
1551
1552
} ;
1552
1553
1553
1554
let mut remaining_segments = path. segments ( ) . skip ( remaining_idx) ;
1554
1555
1556
+ if remaining_segments. len ( ) >= 2 {
1557
+ path_ctx. ignore_last_segment ( ) ;
1558
+ }
1559
+
1555
1560
// We need to try resolving unresolved segments one by one because each may resolve
1556
1561
// to a projection, which `TyLoweringContext` cannot handle on its own.
1557
1562
let mut tried_resolving_once = false ;
1558
- while !remaining_segments. is_empty ( ) {
1559
- let resolved_segment = path. segments ( ) . get ( remaining_idx - 1 ) . unwrap ( ) ;
1560
- let current_segment = remaining_segments. take ( 1 ) ;
1561
-
1563
+ while let Some ( current_segment) = remaining_segments. first ( ) {
1562
1564
// If we can resolve to an enum variant, it takes priority over associated type
1563
1565
// of the same name.
1564
1566
if let Some ( ( AdtId :: EnumId ( id) , _) ) = ty. as_adt ( ) {
1565
1567
let enum_data = self . db . enum_data ( id) ;
1566
- let name = current_segment. first ( ) . unwrap ( ) . name ;
1567
- if let Some ( variant) = enum_data. variant ( name) {
1568
+ if let Some ( variant) = enum_data. variant ( current_segment. name ) {
1568
1569
return if remaining_segments. len ( ) == 1 {
1569
1570
( ty, Some ( variant. into ( ) ) )
1570
1571
} else {
1571
1572
// We still have unresolved paths, but enum variants never have
1572
1573
// associated types!
1574
+ // FIXME: Report an error.
1573
1575
( self . err_ty ( ) , None )
1574
1576
} ;
1575
1577
}
@@ -1578,23 +1580,13 @@ impl<'a> InferenceContext<'a> {
1578
1580
if tried_resolving_once {
1579
1581
// FIXME: with `inherent_associated_types` this is allowed, but our `lower_partly_resolved_path()`
1580
1582
// will need to be updated to err at the correct segment.
1581
- //
1582
- // We need to stop here because otherwise the segment index passed to `lower_partly_resolved_path()`
1583
- // will be incorrect, and that can mess up error reporting.
1584
1583
break ;
1585
1584
}
1586
1585
1587
1586
// `lower_partly_resolved_path()` returns `None` as type namespace unless
1588
1587
// `remaining_segments` is empty, which is never the case here. We don't know
1589
1588
// which namespace the new `ty` is in until normalized anyway.
1590
- ( ty, _) = ctx. lower_partly_resolved_path (
1591
- node,
1592
- resolution,
1593
- resolved_segment,
1594
- current_segment,
1595
- ( remaining_idx - 1 ) as u32 ,
1596
- false ,
1597
- ) ;
1589
+ ( ty, _) = path_ctx. lower_partly_resolved_path ( resolution, false ) ;
1598
1590
tried_resolving_once = true ;
1599
1591
1600
1592
ty = self . table . insert_type_vars ( ty) ;
@@ -1604,8 +1596,6 @@ impl<'a> InferenceContext<'a> {
1604
1596
return ( self . err_ty ( ) , None ) ;
1605
1597
}
1606
1598
1607
- // FIXME(inherent_associated_types): update `resolution` based on `ty` here.
1608
- remaining_idx += 1 ;
1609
1599
remaining_segments = remaining_segments. skip ( 1 ) ;
1610
1600
}
1611
1601
drop ( ctx) ;
@@ -1621,11 +1611,7 @@ impl<'a> InferenceContext<'a> {
1621
1611
( ty, variant)
1622
1612
}
1623
1613
TypeNs :: TypeAliasId ( it) => {
1624
- let resolved_seg = match unresolved {
1625
- None => path. segments ( ) . last ( ) . unwrap ( ) ,
1626
- Some ( n) => path. segments ( ) . get ( path. segments ( ) . len ( ) - n - 1 ) . unwrap ( ) ,
1627
- } ;
1628
- let substs = ctx. substs_from_path_segment ( resolved_seg, it. into ( ) , true , None ) ;
1614
+ let substs = path_ctx. substs_from_path_segment ( it. into ( ) , true , None ) ;
1629
1615
drop ( ctx) ;
1630
1616
let ty = self . db . ty ( it. into ( ) ) ;
1631
1617
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
0 commit comments