diff options
author | Florian Diebold <[email protected]> | 2019-09-16 20:38:27 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-09-17 18:47:45 +0100 |
commit | fe1dfd2b20b256b99f40f6f6421f7c7e12c23e41 (patch) | |
tree | 4ac1178549999db25d67fd7358c4a705cfe629fc /crates/ra_hir/src/ty/lower.rs | |
parent | 406280e52f20e25af609d947efbed8b352ca1249 (diff) |
Refactor some more
Type-relative paths (`<T>::foo`) also need to work in type context, for example
`<T>::Item` is legal. So rather than returning the type ref from the resolver
function, just check it before.
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index e29b68f1a..e6cd5d0be 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -86,6 +86,24 @@ impl Ty { | |||
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | pub(crate) fn from_type_relative_path( | ||
90 | db: &impl HirDatabase, | ||
91 | resolver: &Resolver, | ||
92 | ty: Ty, | ||
93 | remaining_segments: &[PathSegment], | ||
94 | ) -> Ty { | ||
95 | if remaining_segments.len() == 1 { | ||
96 | // resolve unselected assoc types | ||
97 | let segment = &remaining_segments[0]; | ||
98 | Ty::select_associated_type(db, resolver, ty, segment) | ||
99 | } else if remaining_segments.len() > 1 { | ||
100 | // FIXME report error (ambiguous associated type) | ||
101 | Ty::Unknown | ||
102 | } else { | ||
103 | ty | ||
104 | } | ||
105 | } | ||
106 | |||
89 | pub(crate) fn from_partly_resolved_hir_path( | 107 | pub(crate) fn from_partly_resolved_hir_path( |
90 | db: &impl HirDatabase, | 108 | db: &impl HirDatabase, |
91 | resolver: &Resolver, | 109 | resolver: &Resolver, |
@@ -140,20 +158,16 @@ impl Ty { | |||
140 | TypeNs::EnumVariant(_) => return Ty::Unknown, | 158 | TypeNs::EnumVariant(_) => return Ty::Unknown, |
141 | }; | 159 | }; |
142 | 160 | ||
143 | if remaining_segments.len() == 1 { | 161 | Ty::from_type_relative_path(db, resolver, ty, remaining_segments) |
144 | // resolve unselected assoc types | ||
145 | let segment = &remaining_segments[0]; | ||
146 | Ty::select_associated_type(db, resolver, ty, segment) | ||
147 | } else if remaining_segments.len() > 1 { | ||
148 | // FIXME report error (ambiguous associated type) | ||
149 | Ty::Unknown | ||
150 | } else { | ||
151 | ty | ||
152 | } | ||
153 | } | 162 | } |
154 | 163 | ||
155 | pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty { | 164 | pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty { |
156 | // Resolve the path (in type namespace) | 165 | // Resolve the path (in type namespace) |
166 | if let crate::PathKind::Type(type_ref) = &path.kind { | ||
167 | let ty = Ty::from_hir(db, resolver, &type_ref); | ||
168 | let remaining_segments = &path.segments[..]; | ||
169 | return Ty::from_type_relative_path(db, resolver, ty, remaining_segments); | ||
170 | } | ||
157 | let (resolution, remaining_index) = match resolver.resolve_path_in_type_ns(db, path) { | 171 | let (resolution, remaining_index) = match resolver.resolve_path_in_type_ns(db, path) { |
158 | Some(it) => it, | 172 | Some(it) => it, |
159 | None => return Ty::Unknown, | 173 | None => return Ty::Unknown, |