aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-05-15 16:15:40 +0100
committerFlorian Diebold <[email protected]>2020-05-15 16:25:28 +0100
commit3f42b2e837c4672a0fbe953e14ae2fd3fe6fc3b6 (patch)
tree481c93f91eec65f98a82fa28a123140d5a227eea /crates/ra_hir_ty/src/infer
parentd51c1f62178c383363a2d95e865131d9a7b969d0 (diff)
Handle `Self` in values and patterns
I.e. - `Self(x)` or `Self` in tuple/unit struct impls - `Self::Variant(x)` or `Self::Variant` in enum impls - the same in patterns Fixes #4454.
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs35
1 files changed, 34 insertions, 1 deletions
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 2b6bc0f79..1c2e56fb0 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -5,7 +5,7 @@ use std::iter;
5use hir_def::{ 5use hir_def::{
6 path::{Path, PathSegment}, 6 path::{Path, PathSegment},
7 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, 7 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
8 AssocContainerId, AssocItemId, Lookup, 8 AdtId, AssocContainerId, AssocItemId, EnumVariantId, Lookup,
9}; 9};
10use hir_expand::name::Name; 10use hir_expand::name::Name;
11 11
@@ -77,6 +77,18 @@ impl<'a> InferenceContext<'a> {
77 77
78 it.into() 78 it.into()
79 } 79 }
80 ValueNs::ImplSelf(impl_id) => {
81 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
82 let substs = Substs::type_params_for_generics(&generics);
83 let ty = self.db.impl_self_ty(impl_id).subst(&substs);
84 if let Some((AdtId::StructId(struct_id), _)) = ty.as_adt() {
85 let ty = self.db.value_ty(struct_id.into()).subst(&substs);
86 return Some(ty);
87 } else {
88 // FIXME: diagnostic, invalid Self reference
89 return None;
90 }
91 }
80 }; 92 };
81 93
82 let ty = self.db.value_ty(typable); 94 let ty = self.db.value_ty(typable);
@@ -199,6 +211,10 @@ impl<'a> InferenceContext<'a> {
199 return None; 211 return None;
200 } 212 }
201 213
214 if let Some(result) = self.resolve_enum_variant_on_ty(&ty, name, id) {
215 return Some(result);
216 }
217
202 let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone()); 218 let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone());
203 let krate = self.resolver.krate()?; 219 let krate = self.resolver.krate()?;
204 let traits_in_scope = self.resolver.traits_in_scope(self.db.upcast()); 220 let traits_in_scope = self.resolver.traits_in_scope(self.db.upcast());
@@ -250,4 +266,21 @@ impl<'a> InferenceContext<'a> {
250 }, 266 },
251 ) 267 )
252 } 268 }
269
270 fn resolve_enum_variant_on_ty(
271 &mut self,
272 ty: &Ty,
273 name: &Name,
274 id: ExprOrPatId,
275 ) -> Option<(ValueNs, Option<Substs>)> {
276 let (enum_id, subst) = match ty.as_adt() {
277 Some((AdtId::EnumId(e), subst)) => (e, subst),
278 _ => return None,
279 };
280 let enum_data = self.db.enum_data(enum_id);
281 let local_id = enum_data.variant(name)?;
282 let variant = EnumVariantId { parent: enum_id, local_id };
283 self.write_variant_resolution(id, variant.into());
284 Some((ValueNs::EnumVariantId(variant), Some(subst.clone())))
285 }
253} 286}