diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-09-25 21:23:09 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-09-25 21:23:09 +0100 |
commit | 0d277faf6c4052dcc80037fc43b4986980d0814b (patch) | |
tree | 807f32992732a74c591f6a8c85aff354ebea09c6 /crates/ra_hir/src/ty/infer | |
parent | 5704485063bad82e651c8e68f4fa2d333bfdf152 (diff) | |
parent | c35ef5013c3223986ae5111a3720ef8e85c80efc (diff) |
Merge #1914
1914: Resolve trait associated items r=matklad a=flodiebold
E.g. `Default::default` or `<Foo as Default>::default`.
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/infer')
-rw-r--r-- | crates/ra_hir/src/ty/infer/path.rs | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 54aae4f0c..feb7481b2 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! Path expression resolution. | 1 | //! Path expression resolution. |
2 | 2 | ||
3 | use super::{ExprOrPatId, InferenceContext}; | 3 | use super::{ExprOrPatId, InferenceContext, TraitRef}; |
4 | use crate::{ | 4 | use crate::{ |
5 | db::HirDatabase, | 5 | db::HirDatabase, |
6 | resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs}, | 6 | resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs}, |
@@ -91,9 +91,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
91 | let is_before_last = remaining_segments.len() == 1; | 91 | let is_before_last = remaining_segments.len() == 1; |
92 | 92 | ||
93 | match (def, is_before_last) { | 93 | match (def, is_before_last) { |
94 | (TypeNs::Trait(_trait), true) => { | 94 | (TypeNs::Trait(trait_), true) => { |
95 | // FIXME Associated item of trait, e.g. `Default::default` | 95 | let segment = |
96 | None | 96 | remaining_segments.last().expect("there should be at least one segment here"); |
97 | let trait_ref = TraitRef::from_resolved_path( | ||
98 | self.db, | ||
99 | &self.resolver, | ||
100 | trait_, | ||
101 | resolved_segment, | ||
102 | None, | ||
103 | ); | ||
104 | self.resolve_trait_assoc_item(trait_ref, segment, id) | ||
97 | } | 105 | } |
98 | (def, _) => { | 106 | (def, _) => { |
99 | // Either we already have a type (e.g. `Vec::new`), or we have a | 107 | // Either we already have a type (e.g. `Vec::new`), or we have a |
@@ -120,6 +128,45 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
120 | } | 128 | } |
121 | } | 129 | } |
122 | 130 | ||
131 | fn resolve_trait_assoc_item( | ||
132 | &mut self, | ||
133 | trait_ref: TraitRef, | ||
134 | segment: &crate::path::PathSegment, | ||
135 | id: ExprOrPatId, | ||
136 | ) -> Option<(ValueNs, Option<Substs>)> { | ||
137 | let trait_ = trait_ref.trait_; | ||
138 | let item = trait_.items(self.db).iter().copied().find_map(|item| match item { | ||
139 | AssocItem::Function(func) => { | ||
140 | if segment.name == func.name(self.db) { | ||
141 | Some(AssocItem::Function(func)) | ||
142 | } else { | ||
143 | None | ||
144 | } | ||
145 | } | ||
146 | |||
147 | AssocItem::Const(konst) => { | ||
148 | if konst.name(self.db).map_or(false, |n| n == segment.name) { | ||
149 | Some(AssocItem::Const(konst)) | ||
150 | } else { | ||
151 | None | ||
152 | } | ||
153 | } | ||
154 | AssocItem::TypeAlias(_) => None, | ||
155 | })?; | ||
156 | let def = match item { | ||
157 | AssocItem::Function(f) => ValueNs::Function(f), | ||
158 | AssocItem::Const(c) => ValueNs::Const(c), | ||
159 | AssocItem::TypeAlias(_) => unreachable!(), | ||
160 | }; | ||
161 | let generics = item.generic_params(self.db); | ||
162 | let mut substs = Vec::with_capacity(generics.count_params_including_parent()); | ||
163 | substs.extend(trait_ref.substs.iter().cloned()); | ||
164 | substs.extend(std::iter::repeat(Ty::Unknown).take(generics.params.len())); | ||
165 | |||
166 | self.write_assoc_resolution(id, item); | ||
167 | Some((def, Some(substs.into()))) | ||
168 | } | ||
169 | |||
123 | fn resolve_ty_assoc_item( | 170 | fn resolve_ty_assoc_item( |
124 | &mut self, | 171 | &mut self, |
125 | ty: Ty, | 172 | ty: Ty, |