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;
@@ -1502,21 +1502,22 @@ impl<'a> InferenceContext<'a> {
1502
1502
& self . diagnostics ,
1503
1503
InferenceTyDiagnosticSource :: Body ,
1504
1504
) ;
1505
+ let mut path_ctx = ctx. at_path ( path, node) ;
1505
1506
let ( resolution, unresolved) = if value_ns {
1506
- let Some ( res) = ctx . resolve_path_in_value_ns ( path , node , HygieneId :: ROOT ) else {
1507
+ let Some ( res) = path_ctx . resolve_path_in_value_ns ( HygieneId :: ROOT ) else {
1507
1508
return ( self . err_ty ( ) , None ) ;
1508
1509
} ;
1509
1510
match res {
1510
1511
ResolveValueResult :: ValueNs ( value, _) => match value {
1511
1512
ValueNs :: EnumVariantId ( var) => {
1512
- let substs = ctx . substs_from_path ( path , var. into ( ) , true ) ;
1513
+ let substs = path_ctx . substs_from_path ( var. into ( ) , true ) ;
1513
1514
drop ( ctx) ;
1514
1515
let ty = self . db . ty ( var. lookup ( self . db . upcast ( ) ) . parent . into ( ) ) ;
1515
1516
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
1516
1517
return ( ty, Some ( var. into ( ) ) ) ;
1517
1518
}
1518
1519
ValueNs :: StructId ( strukt) => {
1519
- let substs = ctx . substs_from_path ( path , strukt. into ( ) , true ) ;
1520
+ let substs = path_ctx . substs_from_path ( strukt. into ( ) , true ) ;
1520
1521
drop ( ctx) ;
1521
1522
let ty = self . db . ty ( strukt. into ( ) ) ;
1522
1523
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
@@ -1531,7 +1532,7 @@ impl<'a> InferenceContext<'a> {
1531
1532
ResolveValueResult :: Partial ( typens, unresolved, _) => ( typens, Some ( unresolved) ) ,
1532
1533
}
1533
1534
} else {
1534
- match ctx . resolve_path_in_type_ns ( path , node ) {
1535
+ match path_ctx . resolve_path_in_type_ns ( ) {
1535
1536
Some ( ( it, idx) ) => ( it, idx) ,
1536
1537
None => return ( self . err_ty ( ) , None ) ,
1537
1538
}
@@ -1542,21 +1543,21 @@ impl<'a> InferenceContext<'a> {
1542
1543
} ;
1543
1544
return match resolution {
1544
1545
TypeNs :: AdtId ( AdtId :: StructId ( strukt) ) => {
1545
- let substs = ctx . substs_from_path ( path , strukt. into ( ) , true ) ;
1546
+ let substs = path_ctx . substs_from_path ( strukt. into ( ) , true ) ;
1546
1547
drop ( ctx) ;
1547
1548
let ty = self . db . ty ( strukt. into ( ) ) ;
1548
1549
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
1549
1550
forbid_unresolved_segments ( ( ty, Some ( strukt. into ( ) ) ) , unresolved)
1550
1551
}
1551
1552
TypeNs :: AdtId ( AdtId :: UnionId ( u) ) => {
1552
- let substs = ctx . substs_from_path ( path , u. into ( ) , true ) ;
1553
+ let substs = path_ctx . substs_from_path ( u. into ( ) , true ) ;
1553
1554
drop ( ctx) ;
1554
1555
let ty = self . db . ty ( u. into ( ) ) ;
1555
1556
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
1556
1557
forbid_unresolved_segments ( ( ty, Some ( u. into ( ) ) ) , unresolved)
1557
1558
}
1558
1559
TypeNs :: EnumVariantId ( var) => {
1559
- let substs = ctx . substs_from_path ( path , var. into ( ) , true ) ;
1560
+ let substs = path_ctx . substs_from_path ( var. into ( ) , true ) ;
1560
1561
drop ( ctx) ;
1561
1562
let ty = self . db . ty ( var. lookup ( self . db . upcast ( ) ) . parent . into ( ) ) ;
1562
1563
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
@@ -1567,31 +1568,32 @@ impl<'a> InferenceContext<'a> {
1567
1568
let substs = generics. placeholder_subst ( self . db ) ;
1568
1569
let mut ty = self . db . impl_self_ty ( impl_id) . substitute ( Interner , & substs) ;
1569
1570
1570
- let Some ( mut remaining_idx) = unresolved else {
1571
+ let Some ( remaining_idx) = unresolved else {
1571
1572
drop ( ctx) ;
1572
1573
return self . resolve_variant_on_alias ( ty, None , mod_path) ;
1573
1574
} ;
1574
1575
1575
1576
let mut remaining_segments = path. segments ( ) . skip ( remaining_idx) ;
1576
1577
1578
+ if remaining_segments. len ( ) >= 2 {
1579
+ path_ctx. ignore_last_segment ( ) ;
1580
+ }
1581
+
1577
1582
// We need to try resolving unresolved segments one by one because each may resolve
1578
1583
// to a projection, which `TyLoweringContext` cannot handle on its own.
1579
1584
let mut tried_resolving_once = false ;
1580
- while !remaining_segments. is_empty ( ) {
1581
- let resolved_segment = path. segments ( ) . get ( remaining_idx - 1 ) . unwrap ( ) ;
1582
- let current_segment = remaining_segments. take ( 1 ) ;
1583
-
1585
+ while let Some ( current_segment) = remaining_segments. first ( ) {
1584
1586
// If we can resolve to an enum variant, it takes priority over associated type
1585
1587
// of the same name.
1586
1588
if let Some ( ( AdtId :: EnumId ( id) , _) ) = ty. as_adt ( ) {
1587
1589
let enum_data = self . db . enum_data ( id) ;
1588
- let name = current_segment. first ( ) . unwrap ( ) . name ;
1589
- if let Some ( variant) = enum_data. variant ( name) {
1590
+ if let Some ( variant) = enum_data. variant ( current_segment. name ) {
1590
1591
return if remaining_segments. len ( ) == 1 {
1591
1592
( ty, Some ( variant. into ( ) ) )
1592
1593
} else {
1593
1594
// We still have unresolved paths, but enum variants never have
1594
1595
// associated types!
1596
+ // FIXME: Report an error.
1595
1597
( self . err_ty ( ) , None )
1596
1598
} ;
1597
1599
}
@@ -1600,23 +1602,13 @@ impl<'a> InferenceContext<'a> {
1600
1602
if tried_resolving_once {
1601
1603
// FIXME: with `inherent_associated_types` this is allowed, but our `lower_partly_resolved_path()`
1602
1604
// will need to be updated to err at the correct segment.
1603
- //
1604
- // We need to stop here because otherwise the segment index passed to `lower_partly_resolved_path()`
1605
- // will be incorrect, and that can mess up error reporting.
1606
1605
break ;
1607
1606
}
1608
1607
1609
1608
// `lower_partly_resolved_path()` returns `None` as type namespace unless
1610
1609
// `remaining_segments` is empty, which is never the case here. We don't know
1611
1610
// which namespace the new `ty` is in until normalized anyway.
1612
- ( ty, _) = ctx. lower_partly_resolved_path (
1613
- node,
1614
- resolution,
1615
- resolved_segment,
1616
- current_segment,
1617
- ( remaining_idx - 1 ) as u32 ,
1618
- false ,
1619
- ) ;
1611
+ ( ty, _) = path_ctx. lower_partly_resolved_path ( resolution, false ) ;
1620
1612
tried_resolving_once = true ;
1621
1613
1622
1614
ty = self . table . insert_type_vars ( ty) ;
@@ -1626,8 +1618,6 @@ impl<'a> InferenceContext<'a> {
1626
1618
return ( self . err_ty ( ) , None ) ;
1627
1619
}
1628
1620
1629
- // FIXME(inherent_associated_types): update `resolution` based on `ty` here.
1630
- remaining_idx += 1 ;
1631
1621
remaining_segments = remaining_segments. skip ( 1 ) ;
1632
1622
}
1633
1623
drop ( ctx) ;
@@ -1643,12 +1633,7 @@ impl<'a> InferenceContext<'a> {
1643
1633
( ty, variant)
1644
1634
}
1645
1635
TypeNs :: TypeAliasId ( it) => {
1646
- let resolved_seg = match unresolved {
1647
- None => path. segments ( ) . last ( ) . unwrap ( ) ,
1648
- Some ( n) => path. segments ( ) . get ( path. segments ( ) . len ( ) - n - 1 ) . unwrap ( ) ,
1649
- } ;
1650
- let substs =
1651
- ctx. substs_from_path_segment ( resolved_seg, Some ( it. into ( ) ) , true , None ) ;
1636
+ let substs = path_ctx. substs_from_path_segment ( it. into ( ) , true , None ) ;
1652
1637
drop ( ctx) ;
1653
1638
let ty = self . db . ty ( it. into ( ) ) ;
1654
1639
let ty = self . insert_type_vars ( ty. substitute ( Interner , & substs) ) ;
0 commit comments