Skip to content

Commit 1fd0369

Browse files
committed
implement feature(more_qualified_paths)
Specifically, this allows the following patterns and expressions which were not allowed before: ```rust let <T as Trait>::Assoc { a } = <T as Trait>::Assoc { a: 0 }; let (<E as Trait>::Assoc::ES { a } | <E as Trait>::Assoc::ET(a)) = <E as Trait>::Assoc::ES { a: 0 }; let (<E>::ES { a } | <E>::ET(a)) = <E>::ES { a: 0 }; ```
1 parent bf6d445 commit 1fd0369

File tree

1 file changed

+78
-1
lines changed

1 file changed

+78
-1
lines changed

crates/hir-ty/src/infer.rs

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,7 @@ impl<'db> InferenceContext<'db> {
15801580
Some(path) => path,
15811581
None => return (self.err_ty(), None),
15821582
};
1583+
15831584
let mut ctx = TyLoweringContext::new(
15841585
self.db,
15851586
&self.resolver,
@@ -1589,6 +1590,25 @@ impl<'db> InferenceContext<'db> {
15891590
self.generic_def,
15901591
LifetimeElisionKind::Infer,
15911592
);
1593+
1594+
if let Some(type_anchor) = path.type_anchor() {
1595+
let segments = path.segments();
1596+
if segments.len() != 1 {
1597+
return (self.err_ty(), None);
1598+
}
1599+
let ty = ctx.lower_ty(type_anchor);
1600+
if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
1601+
let enum_data = self.db.enum_variants(id);
1602+
if let Some(variant) = enum_data.variant(segments.first().unwrap().name) {
1603+
// FIXME: Report error if there are generics on the variant.
1604+
return (ty, Some(variant.into()));
1605+
}
1606+
} else {
1607+
// FIXME: Report an error.
1608+
return (self.err_ty(), None);
1609+
}
1610+
}
1611+
15921612
let mut path_ctx = ctx.at_path(path, node);
15931613
let (resolution, unresolved) = if value_ns {
15941614
let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else {
@@ -1719,6 +1739,64 @@ impl<'db> InferenceContext<'db> {
17191739
});
17201740
(ty, variant)
17211741
}
1742+
TypeNs::TraitId(_) => {
1743+
// let mut ty = if let Some([Some(args), ..]) = path.generic_args()
1744+
// && args.has_self_type
1745+
// &&args.args.get(0)
1746+
// &&Some(hir_def::expr_store::path::GenericArg::Type(type_idx));)
1747+
// {
1748+
1749+
// }
1750+
// let (true, Some(hir_def::expr_store::path::GenericArg::Type(type_idx))) = (args.has_self_type, args.args.get(0))
1751+
// else {
1752+
// return (self.err_ty(), None);
1753+
// };
1754+
// let mut ty = path_ctx.ty_ctx().lower_ty(type_idx);
1755+
1756+
dbg!(&path);
1757+
let Some(remaining_idx) = unresolved else {
1758+
//drop(ctx);
1759+
return (self.err_ty(), None);
1760+
};
1761+
1762+
let remaining_segments = path.segments().skip(remaining_idx);
1763+
dbg!(&remaining_segments);
1764+
1765+
if remaining_segments.len() >= 2 {
1766+
path_ctx.ignore_last_segment();
1767+
}
1768+
1769+
let (mut ty, _) = path_ctx.lower_partly_resolved_path(resolution, true);
1770+
ty = self.table.insert_type_vars(ty);
1771+
ty = self.table.normalize_associated_types_in(ty);
1772+
ty = self.table.resolve_ty_shallow(&ty);
1773+
1774+
if let Some(segment) = remaining_segments.get(1) {
1775+
if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
1776+
let enum_data = self.db.enum_variants(id);
1777+
if let Some(variant) = enum_data.variant(segment.name) {
1778+
return if remaining_segments.len() == 2 {
1779+
(ty, Some(variant.into()))
1780+
} else {
1781+
// We still have unresolved paths, but enum variants never have
1782+
// associated types!
1783+
// FIXME: Report an error.
1784+
(self.err_ty(), None)
1785+
};
1786+
}
1787+
}
1788+
}
1789+
1790+
let variant = dbg!(ty.as_adt()).and_then(|(id, _)| match id {
1791+
AdtId::StructId(s) => Some(VariantId::StructId(s)),
1792+
AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
1793+
AdtId::EnumId(_) => {
1794+
// FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
1795+
None
1796+
}
1797+
});
1798+
(ty, variant)
1799+
}
17221800
TypeNs::TypeAliasId(it) => {
17231801
let Some(mod_path) = path.mod_path() else {
17241802
never!("resolver should always resolve lang item paths");
@@ -1741,7 +1819,6 @@ impl<'db> InferenceContext<'db> {
17411819
}
17421820
TypeNs::AdtId(AdtId::EnumId(_))
17431821
| TypeNs::BuiltinType(_)
1744-
| TypeNs::TraitId(_)
17451822
| TypeNs::TraitAliasId(_)
17461823
| TypeNs::ModuleId(_) => {
17471824
// FIXME diagnostic

0 commit comments

Comments
 (0)