@@ -1731,6 +1731,88 @@ impl<'db> InferenceContext<'db> {
1731
1731
1732
1732
self . resolve_variant_on_alias ( ty, unresolved, mod_path)
1733
1733
}
1734
+ TypeNs :: TraitId ( _trait_id) => {
1735
+ let Some ( mut remaining_idx) = unresolved else {
1736
+ drop ( ctx) ;
1737
+ return ( self . err_ty ( ) , None ) ;
1738
+ } ;
1739
+
1740
+ let mut remaining_segments = path. segments ( ) . skip ( remaining_idx) ;
1741
+
1742
+ let mut ty;
1743
+
1744
+ // We need to try resolving unresolved segments one by one because each may resolve
1745
+ // to a projection, which `TyLoweringContext` cannot handle on its own.
1746
+ let mut tried_resolving_once;
1747
+ loop {
1748
+ let resolved_segment = path. segments ( ) . get ( remaining_idx - 1 ) . unwrap ( ) ;
1749
+ let current_segment = remaining_segments. take ( 1 ) ;
1750
+
1751
+ // `lower_partly_resolved_path()` returns `None` as type namespace unless
1752
+ // `remaining_segments` is empty, which is never the case here. We don't know
1753
+ // which namespace the new `ty` is in until normalized anyway.
1754
+ ( ty, _) = ctx. lower_partly_resolved_path (
1755
+ node,
1756
+ resolution,
1757
+ resolved_segment,
1758
+ current_segment,
1759
+ ( remaining_idx - 1 ) as u32 ,
1760
+ false ,
1761
+ ) ;
1762
+ tried_resolving_once = true ;
1763
+
1764
+ ty = self . table . insert_type_vars ( ty) ;
1765
+ ty = self . table . normalize_associated_types_in ( ty) ;
1766
+ ty = self . table . resolve_ty_shallow ( & ty) ;
1767
+ if ty. is_unknown ( ) {
1768
+ return ( self . err_ty ( ) , None ) ;
1769
+ }
1770
+
1771
+ // FIXME(inherent_associated_types): update `resolution` based on `ty` here.
1772
+ remaining_idx += 1 ;
1773
+ remaining_segments = remaining_segments. skip ( 1 ) ;
1774
+
1775
+ // If we can resolve to an enum variant, it takes priority over associated type
1776
+ // of the same name.
1777
+ if let Some ( ( AdtId :: EnumId ( id) , _) ) = ty. as_adt ( ) {
1778
+ let enum_data = self . db . enum_data ( id) ;
1779
+ let name = current_segment. first ( ) . unwrap ( ) . name ;
1780
+ if let Some ( variant) = enum_data. variant ( name) {
1781
+ return if remaining_segments. len ( ) == 1 {
1782
+ ( ty, Some ( variant. into ( ) ) )
1783
+ } else {
1784
+ // We still have unresolved paths, but enum variants never have
1785
+ // associated types!
1786
+ ( self . err_ty ( ) , None )
1787
+ } ;
1788
+ }
1789
+ }
1790
+
1791
+ if tried_resolving_once {
1792
+ // FIXME: with `inherent_associated_types` this is allowed, but our `lower_partly_resolved_path()`
1793
+ // will need to be updated to err at the correct segment.
1794
+ //
1795
+ // We need to stop here because otherwise the segment index passed to `lower_partly_resolved_path()`
1796
+ // will be incorrect, and that can mess up error reporting.
1797
+ break ;
1798
+ }
1799
+
1800
+ if remaining_segments. is_empty ( ) {
1801
+ break ;
1802
+ }
1803
+ }
1804
+ drop ( ctx) ;
1805
+
1806
+ let variant = ty. as_adt ( ) . and_then ( |( id, _) | match id {
1807
+ AdtId :: StructId ( s) => Some ( VariantId :: StructId ( s) ) ,
1808
+ AdtId :: UnionId ( u) => Some ( VariantId :: UnionId ( u) ) ,
1809
+ AdtId :: EnumId ( _) => {
1810
+ // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
1811
+ None
1812
+ }
1813
+ } ) ;
1814
+ ( ty, variant)
1815
+ }
1734
1816
TypeNs :: AdtSelfType ( _) => {
1735
1817
// FIXME this could happen in array size expressions, once we're checking them
1736
1818
( self . err_ty ( ) , None )
@@ -1741,7 +1823,6 @@ impl<'db> InferenceContext<'db> {
1741
1823
}
1742
1824
TypeNs :: AdtId ( AdtId :: EnumId ( _) )
1743
1825
| TypeNs :: BuiltinType ( _)
1744
- | TypeNs :: TraitId ( _)
1745
1826
| TypeNs :: TraitAliasId ( _)
1746
1827
| TypeNs :: ModuleId ( _) => {
1747
1828
// FIXME diagnostic
0 commit comments