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