aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r--crates/ra_hir_ty/src/lower.rs70
1 files changed, 34 insertions, 36 deletions
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 =