aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-12-13 11:12:36 +0000
committerAleksey Kladov <[email protected]>2019-12-14 18:15:40 +0000
commit2619950b3b405324ab1c1745876165c834b3b4b9 (patch)
tree1f32b3f34bbdad0d58b3cbddf250c350cd546de6 /crates/ra_hir_ty
parentf720855e1e45985463e31e0a6a2a76bb6ffd1cfa (diff)
Use different types for path with and without generics
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/infer.rs2
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs25
-rw-r--r--crates/ra_hir_ty/src/lower.rs70
-rw-r--r--crates/ra_hir_ty/src/utils.rs5
4 files changed, 51 insertions, 51 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index f1b7e9442..af42854cc 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -386,7 +386,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
386 let resolver = &self.resolver; 386 let resolver = &self.resolver;
387 // FIXME: this should resolve assoc items as well, see this example: 387 // FIXME: this should resolve assoc items as well, see this example:
388 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 388 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
389 match resolver.resolve_path_in_type_ns_fully(self.db, &path) { 389 match resolver.resolve_path_in_type_ns_fully(self.db, path.mod_path()) {
390 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => { 390 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => {
391 let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); 391 let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into());
392 let ty = self.db.ty(strukt.into()); 392 let ty = self.db.ty(strukt.into());
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 37db005ea..3bae0ca6c 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -32,21 +32,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
32 path: &Path, 32 path: &Path,
33 id: ExprOrPatId, 33 id: ExprOrPatId,
34 ) -> Option<Ty> { 34 ) -> Option<Ty> {
35 let (value, self_subst) = if let PathKind::Type(type_ref) = &path.kind { 35 let (value, self_subst) = if let PathKind::Type(type_ref) = path.kind() {
36 if path.segments.is_empty() { 36 if path.segments().is_empty() {
37 // This can't actually happen syntax-wise 37 // This can't actually happen syntax-wise
38 return None; 38 return None;
39 } 39 }
40 let ty = self.make_ty(type_ref); 40 let ty = self.make_ty(type_ref);
41 let remaining_segments_for_ty = &path.segments[..path.segments.len() - 1]; 41 let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1);
42 let ty = Ty::from_type_relative_path(self.db, resolver, ty, remaining_segments_for_ty); 42 let ty = Ty::from_type_relative_path(self.db, resolver, ty, remaining_segments_for_ty);
43 self.resolve_ty_assoc_item( 43 self.resolve_ty_assoc_item(
44 ty, 44 ty,
45 &path.segments.last().expect("path had at least one segment").name, 45 &path.segments().last().expect("path had at least one segment").name,
46 id, 46 id,
47 )? 47 )?
48 } else { 48 } else {
49 let value_or_partial = resolver.resolve_path_in_value_ns(self.db, &path)?; 49 let value_or_partial = resolver.resolve_path_in_value_ns(self.db, path.mod_path())?;
50 50
51 match value_or_partial { 51 match value_or_partial {
52 ResolveValueResult::ValueNs(it) => (it, None), 52 ResolveValueResult::ValueNs(it) => (it, None),
@@ -85,13 +85,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
85 remaining_index: usize, 85 remaining_index: usize,
86 id: ExprOrPatId, 86 id: ExprOrPatId,
87 ) -> Option<(ValueNs, Option<Substs>)> { 87 ) -> Option<(ValueNs, Option<Substs>)> {
88 assert!(remaining_index < path.segments.len()); 88 assert!(remaining_index < path.segments().len());
89 // there may be more intermediate segments between the resolved one and 89 // there may be more intermediate segments between the resolved one and
90 // the end. Only the last segment needs to be resolved to a value; from 90 // the end. Only the last segment needs to be resolved to a value; from
91 // the segments before that, we need to get either a type or a trait ref. 91 // the segments before that, we need to get either a type or a trait ref.
92 92
93 let resolved_segment = &path.segments[remaining_index - 1]; 93 let resolved_segment = path.segments().get(remaining_index - 1).unwrap();
94 let remaining_segments = &path.segments[remaining_index..]; 94 let remaining_segments = path.segments().skip(remaining_index);
95 let is_before_last = remaining_segments.len() == 1; 95 let is_before_last = remaining_segments.len() == 1;
96 96
97 match (def, is_before_last) { 97 match (def, is_before_last) {
@@ -112,7 +112,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
112 // trait but it's not the last segment, so the next segment 112 // trait but it's not the last segment, so the next segment
113 // should resolve to an associated type of that trait (e.g. `<T 113 // should resolve to an associated type of that trait (e.g. `<T
114 // as Iterator>::Item::default`) 114 // as Iterator>::Item::default`)
115 let remaining_segments_for_ty = &remaining_segments[..remaining_segments.len() - 1]; 115 let remaining_segments_for_ty =
116 remaining_segments.take(remaining_segments.len() - 1);
116 let ty = Ty::from_partly_resolved_hir_path( 117 let ty = Ty::from_partly_resolved_hir_path(
117 self.db, 118 self.db,
118 &self.resolver, 119 &self.resolver,
@@ -138,7 +139,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
138 fn resolve_trait_assoc_item( 139 fn resolve_trait_assoc_item(
139 &mut self, 140 &mut self,
140 trait_ref: TraitRef, 141 trait_ref: TraitRef,
141 segment: &PathSegment, 142 segment: PathSegment<'_>,
142 id: ExprOrPatId, 143 id: ExprOrPatId,
143 ) -> Option<(ValueNs, Option<Substs>)> { 144 ) -> Option<(ValueNs, Option<Substs>)> {
144 let trait_ = trait_ref.trait_; 145 let trait_ = trait_ref.trait_;
@@ -150,7 +151,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
150 .map(|(_name, id)| (*id).into()) 151 .map(|(_name, id)| (*id).into())
151 .find_map(|item| match item { 152 .find_map(|item| match item {
152 AssocItemId::FunctionId(func) => { 153 AssocItemId::FunctionId(func) => {
153 if segment.name == self.db.function_data(func).name { 154 if segment.name == &self.db.function_data(func).name {
154 Some(AssocItemId::FunctionId(func)) 155 Some(AssocItemId::FunctionId(func))
155 } else { 156 } else {
156 None 157 None
@@ -158,7 +159,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
158 } 159 }
159 160
160 AssocItemId::ConstId(konst) => { 161 AssocItemId::ConstId(konst) => {
161 if self.db.const_data(konst).name.as_ref().map_or(false, |n| n == &segment.name) 162 if self.db.const_data(konst).name.as_ref().map_or(false, |n| n == segment.name)
162 { 163 {
163 Some(AssocItemId::ConstId(konst)) 164 Some(AssocItemId::ConstId(konst))
164 } else { 165 } else {
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index 5f795bc02..a4ddfc8ef 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -11,7 +11,7 @@ use std::sync::Arc;
11use hir_def::{ 11use hir_def::{
12 builtin_type::BuiltinType, 12 builtin_type::BuiltinType,
13 generics::WherePredicate, 13 generics::WherePredicate,
14 path::{GenericArg, Path, PathKind, PathSegment}, 14 path::{GenericArg, Path, PathKind, PathSegment, PathSegments},
15 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
16 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, 17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId,
@@ -101,13 +101,13 @@ impl Ty {
101 TypeRef::Path(path) => path, 101 TypeRef::Path(path) => path,
102 _ => return None, 102 _ => return None,
103 }; 103 };
104 if let PathKind::Type(_) = &path.kind { 104 if let PathKind::Type(_) = path.kind() {
105 return None; 105 return None;
106 } 106 }
107 if path.segments.len() > 1 { 107 if path.segments().len() > 1 {
108 return None; 108 return None;
109 } 109 }
110 let resolution = match resolver.resolve_path_in_type_ns(db, path) { 110 let resolution = match resolver.resolve_path_in_type_ns(db, path.mod_path()) {
111 Some((it, None)) => it, 111 Some((it, None)) => it,
112 _ => return None, 112 _ => return None,
113 }; 113 };
@@ -124,11 +124,11 @@ impl Ty {
124 db: &impl HirDatabase, 124 db: &impl HirDatabase,
125 resolver: &Resolver, 125 resolver: &Resolver,
126 ty: Ty, 126 ty: Ty,
127 remaining_segments: &[PathSegment], 127 remaining_segments: PathSegments<'_>,
128 ) -> Ty { 128 ) -> Ty {
129 if remaining_segments.len() == 1 { 129 if remaining_segments.len() == 1 {
130 // resolve unselected assoc types 130 // resolve unselected assoc types
131 let segment = &remaining_segments[0]; 131 let segment = remaining_segments.first().unwrap();
132 Ty::select_associated_type(db, resolver, ty, segment) 132 Ty::select_associated_type(db, resolver, ty, segment)
133 } else if remaining_segments.len() > 1 { 133 } else if remaining_segments.len() > 1 {
134 // FIXME report error (ambiguous associated type) 134 // FIXME report error (ambiguous associated type)
@@ -142,15 +142,15 @@ impl Ty {
142 db: &impl HirDatabase, 142 db: &impl HirDatabase,
143 resolver: &Resolver, 143 resolver: &Resolver,
144 resolution: TypeNs, 144 resolution: TypeNs,
145 resolved_segment: &PathSegment, 145 resolved_segment: PathSegment<'_>,
146 remaining_segments: &[PathSegment], 146 remaining_segments: PathSegments<'_>,
147 ) -> Ty { 147 ) -> Ty {
148 let ty = match resolution { 148 let ty = match resolution {
149 TypeNs::TraitId(trait_) => { 149 TypeNs::TraitId(trait_) => {
150 let trait_ref = 150 let trait_ref =
151 TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None); 151 TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None);
152 return if remaining_segments.len() == 1 { 152 return if remaining_segments.len() == 1 {
153 let segment = &remaining_segments[0]; 153 let segment = remaining_segments.first().unwrap();
154 let associated_ty = associated_type_by_name_including_super_traits( 154 let associated_ty = associated_type_by_name_including_super_traits(
155 db, 155 db,
156 trait_ref.trait_, 156 trait_ref.trait_,
@@ -202,21 +202,21 @@ impl Ty {
202 202
203 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty { 203 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty {
204 // Resolve the path (in type namespace) 204 // Resolve the path (in type namespace)
205 if let PathKind::Type(type_ref) = &path.kind { 205 if let PathKind::Type(type_ref) = path.kind() {
206 let ty = Ty::from_hir(db, resolver, &type_ref); 206 let ty = Ty::from_hir(db, resolver, &type_ref);
207 let remaining_segments = &path.segments[..]; 207 return Ty::from_type_relative_path(db, resolver, ty, path.segments());
208 return Ty::from_type_relative_path(db, resolver, ty, remaining_segments);
209 } 208 }
210 let (resolution, remaining_index) = match resolver.resolve_path_in_type_ns(db, path) { 209 let (resolution, remaining_index) =
211 Some(it) => it, 210 match resolver.resolve_path_in_type_ns(db, path.mod_path()) {
212 None => return Ty::Unknown, 211 Some(it) => it,
213 }; 212 None => return Ty::Unknown,
213 };
214 let (resolved_segment, remaining_segments) = match remaining_index { 214 let (resolved_segment, remaining_segments) = match remaining_index {
215 None => ( 215 None => (
216 path.segments.last().expect("resolved path has at least one element"), 216 path.segments().last().expect("resolved path has at least one element"),
217 &[] as &[PathSegment], 217 PathSegments::EMPTY,
218 ), 218 ),
219 Some(i) => (&path.segments[i - 1], &path.segments[i..]), 219 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
220 }; 220 };
221 Ty::from_partly_resolved_hir_path( 221 Ty::from_partly_resolved_hir_path(
222 db, 222 db,
@@ -231,7 +231,7 @@ impl Ty {
231 db: &impl HirDatabase, 231 db: &impl HirDatabase,
232 resolver: &Resolver, 232 resolver: &Resolver,
233 self_ty: Ty, 233 self_ty: Ty,
234 segment: &PathSegment, 234 segment: PathSegment<'_>,
235 ) -> Ty { 235 ) -> Ty {
236 let param_idx = match self_ty { 236 let param_idx = match self_ty {
237 Ty::Param { idx, .. } => idx, 237 Ty::Param { idx, .. } => idx,
@@ -261,7 +261,7 @@ impl Ty {
261 fn from_hir_path_inner( 261 fn from_hir_path_inner(
262 db: &impl HirDatabase, 262 db: &impl HirDatabase,
263 resolver: &Resolver, 263 resolver: &Resolver,
264 segment: &PathSegment, 264 segment: PathSegment<'_>,
265 typable: TyDefId, 265 typable: TyDefId,
266 ) -> Ty { 266 ) -> Ty {
267 let generic_def = match typable { 267 let generic_def = match typable {
@@ -284,7 +284,7 @@ impl Ty {
284 // special-case enum variants 284 // special-case enum variants
285 resolved: ValueTyDefId, 285 resolved: ValueTyDefId,
286 ) -> Substs { 286 ) -> Substs {
287 let last = path.segments.last().expect("path should have at least one segment"); 287 let last = path.segments().last().expect("path should have at least one segment");
288 let (segment, generic_def) = match resolved { 288 let (segment, generic_def) = match resolved {
289 ValueTyDefId::FunctionId(it) => (last, Some(it.into())), 289 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
290 ValueTyDefId::StructId(it) => (last, Some(it.into())), 290 ValueTyDefId::StructId(it) => (last, Some(it.into())),
@@ -296,13 +296,11 @@ impl Ty {
296 // referring to the variant. So `Option::<T>::None` and 296 // referring to the variant. So `Option::<T>::None` and
297 // `Option::None::<T>` are both allowed (though the former is 297 // `Option::None::<T>` are both allowed (though the former is
298 // preferred). See also `def_ids_for_path_segments` in rustc. 298 // preferred). See also `def_ids_for_path_segments` in rustc.
299 let len = path.segments.len(); 299 let len = path.segments().len();
300 let segment = if len >= 2 && path.segments[len - 2].args_and_bindings.is_some() { 300 let penultimate = if len >= 2 { path.segments().get(len - 2) } else { None };
301 // Option::<T>::None 301 let segment = match penultimate {
302 &path.segments[len - 2] 302 Some(segment) if segment.args_and_bindings.is_some() => segment,
303 } else { 303 _ => last,
304 // Option::None::<T>
305 last
306 }; 304 };
307 (segment, Some(var.parent.into())) 305 (segment, Some(var.parent.into()))
308 } 306 }
@@ -314,7 +312,7 @@ impl Ty {
314pub(super) fn substs_from_path_segment( 312pub(super) fn substs_from_path_segment(
315 db: &impl HirDatabase, 313 db: &impl HirDatabase,
316 resolver: &Resolver, 314 resolver: &Resolver,
317 segment: &PathSegment, 315 segment: PathSegment<'_>,
318 def_generic: Option<GenericDefId>, 316 def_generic: Option<GenericDefId>,
319 add_self_param: bool, 317 add_self_param: bool,
320) -> Substs { 318) -> Substs {
@@ -372,11 +370,11 @@ impl TraitRef {
372 path: &Path, 370 path: &Path,
373 explicit_self_ty: Option<Ty>, 371 explicit_self_ty: Option<Ty>,
374 ) -> Option<Self> { 372 ) -> Option<Self> {
375 let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? { 373 let resolved = match resolver.resolve_path_in_type_ns_fully(db, path.mod_path())? {
376 TypeNs::TraitId(tr) => tr, 374 TypeNs::TraitId(tr) => tr,
377 _ => return None, 375 _ => return None,
378 }; 376 };
379 let segment = path.segments.last().expect("path should have at least one segment"); 377 let segment = path.segments().last().expect("path should have at least one segment");
380 Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty)) 378 Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty))
381 } 379 }
382 380
@@ -384,7 +382,7 @@ impl TraitRef {
384 db: &impl HirDatabase, 382 db: &impl HirDatabase,
385 resolver: &Resolver, 383 resolver: &Resolver,
386 resolved: TraitId, 384 resolved: TraitId,
387 segment: &PathSegment, 385 segment: PathSegment<'_>,
388 explicit_self_ty: Option<Ty>, 386 explicit_self_ty: Option<Ty>,
389 ) -> Self { 387 ) -> Self {
390 let mut substs = TraitRef::substs_from_path(db, resolver, segment, resolved); 388 let mut substs = TraitRef::substs_from_path(db, resolver, segment, resolved);
@@ -410,7 +408,7 @@ impl TraitRef {
410 fn substs_from_path( 408 fn substs_from_path(
411 db: &impl HirDatabase, 409 db: &impl HirDatabase,
412 resolver: &Resolver, 410 resolver: &Resolver,
413 segment: &PathSegment, 411 segment: PathSegment<'_>,
414 resolved: TraitId, 412 resolved: TraitId,
415 ) -> Substs { 413 ) -> Substs {
416 let has_self_param = 414 let has_self_param =
@@ -464,12 +462,12 @@ fn assoc_type_bindings_from_type_bound<'a>(
464 trait_ref: TraitRef, 462 trait_ref: TraitRef,
465) -> impl Iterator<Item = GenericPredicate> + 'a { 463) -> impl Iterator<Item = GenericPredicate> + 'a {
466 let last_segment = match bound { 464 let last_segment = match bound {
467 TypeBound::Path(path) => path.segments.last(), 465 TypeBound::Path(path) => path.segments().last(),
468 TypeBound::Error => None, 466 TypeBound::Error => None,
469 }; 467 };
470 last_segment 468 last_segment
471 .into_iter() 469 .into_iter()
472 .flat_map(|segment| segment.args_and_bindings.iter()) 470 .flat_map(|segment| segment.args_and_bindings.into_iter())
473 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) 471 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
474 .map(move |(name, type_ref)| { 472 .map(move |(name, type_ref)| {
475 let associated_ty = 473 let associated_ty =
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs
index 0049d3c6f..29799a8cb 100644
--- a/crates/ra_hir_ty/src/utils.rs
+++ b/crates/ra_hir_ty/src/utils.rs
@@ -6,6 +6,7 @@ use hir_def::{
6 adt::VariantData, 6 adt::VariantData,
7 db::DefDatabase, 7 db::DefDatabase,
8 generics::{GenericParams, TypeParamData}, 8 generics::{GenericParams, TypeParamData},
9 path::Path,
9 resolver::{HasResolver, TypeNs}, 10 resolver::{HasResolver, TypeNs},
10 type_ref::TypeRef, 11 type_ref::TypeRef,
11 ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId, 12 ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId,
@@ -22,10 +23,10 @@ fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> {
22 .where_predicates 23 .where_predicates
23 .iter() 24 .iter()
24 .filter_map(|pred| match &pred.type_ref { 25 .filter_map(|pred| match &pred.type_ref {
25 TypeRef::Path(p) if p.as_ident() == Some(&name![Self]) => pred.bound.as_path(), 26 TypeRef::Path(p) if p == &Path::from(name![Self]) => pred.bound.as_path(),
26 _ => None, 27 _ => None,
27 }) 28 })
28 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { 29 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) {
29 Some(TypeNs::TraitId(t)) => Some(t), 30 Some(TypeNs::TraitId(t)) => Some(t),
30 _ => None, 31 _ => None,
31 }) 32 })