@@ -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