diff options
-rw-r--r-- | crates/ra_hir_ty/src/db.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/coerce.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/pat.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 49 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 108 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/method_resolution.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/utils.rs | 30 |
11 files changed, 136 insertions, 127 deletions
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs index fea122a8b..7684ade06 100644 --- a/crates/ra_hir_ty/src/db.rs +++ b/crates/ra_hir_ty/src/db.rs | |||
@@ -3,10 +3,10 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{ | 5 | use hir_def::{ |
6 | db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId, | 6 | db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId, TypeParamId, |
7 | }; | 7 | }; |
8 | use ra_arena::map::ArenaMap; | 8 | use ra_arena::map::ArenaMap; |
9 | use ra_db::{salsa, CrateId}; | 9 | use ra_db::{impl_intern_key, salsa, CrateId}; |
10 | use ra_prof::profile; | 10 | use ra_prof::profile; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
@@ -37,10 +37,10 @@ pub trait HirDatabase: DefDatabase { | |||
37 | fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>; | 37 | fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>; |
38 | 38 | ||
39 | #[salsa::invoke(crate::lower::impl_trait_query)] | 39 | #[salsa::invoke(crate::lower::impl_trait_query)] |
40 | fn impl_trait(&self, def: ImplId) -> Option<TraitRef>; | 40 | fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>; |
41 | 41 | ||
42 | #[salsa::invoke(crate::lower::field_types_query)] | 42 | #[salsa::invoke(crate::lower::field_types_query)] |
43 | fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; | 43 | fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Binders<Ty>>>; |
44 | 44 | ||
45 | #[salsa::invoke(crate::callable_item_sig)] | 45 | #[salsa::invoke(crate::callable_item_sig)] |
46 | fn callable_item_signature(&self, def: CallableDef) -> PolyFnSig; | 46 | fn callable_item_signature(&self, def: CallableDef) -> PolyFnSig; |
@@ -49,8 +49,7 @@ pub trait HirDatabase: DefDatabase { | |||
49 | #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] | 49 | #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] |
50 | fn generic_predicates_for_param( | 50 | fn generic_predicates_for_param( |
51 | &self, | 51 | &self, |
52 | def: GenericDefId, | 52 | param_id: TypeParamId, |
53 | param_idx: u32, | ||
54 | ) -> Arc<[GenericPredicate]>; | 53 | ) -> Arc<[GenericPredicate]>; |
55 | 54 | ||
56 | #[salsa::invoke(crate::lower::generic_predicates_query)] | 55 | #[salsa::invoke(crate::lower::generic_predicates_query)] |
@@ -77,6 +76,8 @@ pub trait HirDatabase: DefDatabase { | |||
77 | #[salsa::interned] | 76 | #[salsa::interned] |
78 | fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId; | 77 | fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId; |
79 | #[salsa::interned] | 78 | #[salsa::interned] |
79 | fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; | ||
80 | #[salsa::interned] | ||
80 | fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; | 81 | fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; |
81 | #[salsa::interned] | 82 | #[salsa::interned] |
82 | fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId; | 83 | fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId; |
@@ -117,3 +118,7 @@ fn infer(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> { | |||
117 | fn hir_database_is_object_safe() { | 118 | fn hir_database_is_object_safe() { |
118 | fn _assert_object_safe(_: &dyn HirDatabase) {} | 119 | fn _assert_object_safe(_: &dyn HirDatabase) {} |
119 | } | 120 | } |
121 | |||
122 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
123 | pub struct GlobalTypeParamId(salsa::InternId); | ||
124 | impl_intern_key!(GlobalTypeParamId); | ||
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index 83c0c2c3f..2a9567898 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs | |||
@@ -57,8 +57,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
57 | let trait_ref = db.impl_trait(impl_id)?; | 57 | let trait_ref = db.impl_trait(impl_id)?; |
58 | 58 | ||
59 | // `CoerseUnsized` has one generic parameter for the target type. | 59 | // `CoerseUnsized` has one generic parameter for the target type. |
60 | let cur_from_ty = trait_ref.substs.0.get(0)?; | 60 | let cur_from_ty = trait_ref.value.substs.0.get(0)?; |
61 | let cur_to_ty = trait_ref.substs.0.get(1)?; | 61 | let cur_to_ty = trait_ref.value.substs.0.get(1)?; |
62 | 62 | ||
63 | match (&cur_from_ty, cur_to_ty) { | 63 | match (&cur_from_ty, cur_to_ty) { |
64 | (ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => { | 64 | (ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => { |
@@ -66,8 +66,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
66 | // This works for smart-pointer-like coercion, which covers all impls from std. | 66 | // This works for smart-pointer-like coercion, which covers all impls from std. |
67 | st1.iter().zip(st2.iter()).enumerate().find_map(|(i, (ty1, ty2))| { | 67 | st1.iter().zip(st2.iter()).enumerate().find_map(|(i, (ty1, ty2))| { |
68 | match (ty1, ty2) { | 68 | match (ty1, ty2) { |
69 | (Ty::Param { idx: p1, .. }, Ty::Param { idx: p2, .. }) | 69 | (Ty::Bound(idx1), Ty::Bound(idx2)) |
70 | if p1 != p2 => | 70 | if idx1 != idx2 => |
71 | { | 71 | { |
72 | Some(((*ctor1, *ctor2), i)) | 72 | Some(((*ctor1, *ctor2), i)) |
73 | } | 73 | } |
@@ -256,8 +256,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
256 | let unsize_generic_index = { | 256 | let unsize_generic_index = { |
257 | let mut index = None; | 257 | let mut index = None; |
258 | let mut multiple_param = false; | 258 | let mut multiple_param = false; |
259 | field_tys[last_field_id].walk(&mut |ty| match ty { | 259 | field_tys[last_field_id].value.walk(&mut |ty| match ty { |
260 | &Ty::Param { idx, .. } => { | 260 | &Ty::Bound(idx) => { |
261 | if index.is_none() { | 261 | if index.is_none() { |
262 | index = Some(idx); | 262 | index = Some(idx); |
263 | } else if Some(idx) != index { | 263 | } else if Some(idx) != index { |
@@ -276,8 +276,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
276 | // Check other fields do not involve it. | 276 | // Check other fields do not involve it. |
277 | let mut multiple_used = false; | 277 | let mut multiple_used = false; |
278 | fields.for_each(|(field_id, _data)| { | 278 | fields.for_each(|(field_id, _data)| { |
279 | field_tys[field_id].walk(&mut |ty| match ty { | 279 | field_tys[field_id].value.walk(&mut |ty| match ty { |
280 | &Ty::Param { idx, .. } if idx == unsize_generic_index => { | 280 | &Ty::Bound(idx) if idx == unsize_generic_index => { |
281 | multiple_used = true | 281 | multiple_used = true |
282 | } | 282 | } |
283 | _ => {} | 283 | _ => {} |
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index e1fdb356d..8b8378499 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -236,8 +236,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
236 | self.result.record_field_resolutions.insert(field.expr, field_def); | 236 | self.result.record_field_resolutions.insert(field.expr, field_def); |
237 | } | 237 | } |
238 | let field_ty = field_def | 238 | let field_ty = field_def |
239 | .map_or(Ty::Unknown, |it| field_types[it.local_id].clone()) | 239 | .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs)); |
240 | .subst(&substs); | ||
241 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); | 240 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
242 | } | 241 | } |
243 | if let Some(expr) = spread { | 242 | if let Some(expr) = spread { |
@@ -686,7 +685,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
686 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 685 | if let TypeCtor::FnDef(def) = a_ty.ctor { |
687 | let generic_predicates = self.db.generic_predicates(def.into()); | 686 | let generic_predicates = self.db.generic_predicates(def.into()); |
688 | for predicate in generic_predicates.iter() { | 687 | for predicate in generic_predicates.iter() { |
689 | let predicate = predicate.clone().subst(&a_ty.parameters); | 688 | let predicate = predicate.clone().subst_type_params(self.db, def.into(), &a_ty.parameters); |
690 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 689 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
691 | self.obligations.push(obligation); | 690 | self.obligations.push(obligation); |
692 | } | 691 | } |
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index a14662884..e7283f24c 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs | |||
@@ -12,7 +12,7 @@ use hir_expand::name::Name; | |||
12 | use test_utils::tested_by; | 12 | use test_utils::tested_by; |
13 | 13 | ||
14 | use super::{BindingMode, InferenceContext}; | 14 | use super::{BindingMode, InferenceContext}; |
15 | use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, TypeWalk}; | 15 | use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor}; |
16 | 16 | ||
17 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 17 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
18 | fn infer_tuple_struct_pat( | 18 | fn infer_tuple_struct_pat( |
@@ -34,8 +34,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
34 | let expected_ty = var_data | 34 | let expected_ty = var_data |
35 | .as_ref() | 35 | .as_ref() |
36 | .and_then(|d| d.field(&Name::new_tuple_field(i))) | 36 | .and_then(|d| d.field(&Name::new_tuple_field(i))) |
37 | .map_or(Ty::Unknown, |field| field_tys[field].clone()) | 37 | .map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); |
38 | .subst(&substs); | ||
39 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 38 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
40 | self.infer_pat(subpat, &expected_ty, default_bm); | 39 | self.infer_pat(subpat, &expected_ty, default_bm); |
41 | } | 40 | } |
@@ -65,7 +64,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
65 | for subpat in subpats { | 64 | for subpat in subpats { |
66 | let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); | 65 | let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); |
67 | let expected_ty = | 66 | let expected_ty = |
68 | matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone()).subst(&substs); | 67 | matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); |
69 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 68 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
70 | self.infer_pat(subpat.pat, &expected_ty, default_bm); | 69 | self.infer_pat(subpat.pat, &expected_ty, default_bm); |
71 | } | 70 | } |
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 1f0fd1128..1e162943c 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -45,10 +45,10 @@ use std::{fmt, iter, mem}; | |||
45 | 45 | ||
46 | use hir_def::{ | 46 | use hir_def::{ |
47 | expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, | 47 | expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, |
48 | HasModule, Lookup, TraitId, TypeAliasId, | 48 | HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, generics::TypeParamProvenance, |
49 | }; | 49 | }; |
50 | use hir_expand::name::Name; | ||
51 | use ra_db::{impl_intern_key, salsa, CrateId}; | 50 | use ra_db::{impl_intern_key, salsa, CrateId}; |
51 | use hir_expand::name::Name; | ||
52 | 52 | ||
53 | use crate::{ | 53 | use crate::{ |
54 | db::HirDatabase, | 54 | db::HirDatabase, |
@@ -288,14 +288,7 @@ pub enum Ty { | |||
288 | Projection(ProjectionTy), | 288 | Projection(ProjectionTy), |
289 | 289 | ||
290 | /// A type parameter; for example, `T` in `fn f<T>(x: T) {} | 290 | /// A type parameter; for example, `T` in `fn f<T>(x: T) {} |
291 | Param { | 291 | Param(TypeParamId), |
292 | /// The index of the parameter (starting with parameters from the | ||
293 | /// surrounding impl, then the current function). | ||
294 | idx: u32, | ||
295 | /// The name of the parameter, for displaying. | ||
296 | // FIXME get rid of this | ||
297 | name: Name, | ||
298 | }, | ||
299 | 292 | ||
300 | /// A bound type variable. Used during trait resolution to represent Chalk | 293 | /// A bound type variable. Used during trait resolution to represent Chalk |
301 | /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type. | 294 | /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type. |
@@ -366,15 +359,15 @@ impl Substs { | |||
366 | } | 359 | } |
367 | 360 | ||
368 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | 361 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). |
369 | pub(crate) fn identity(generic_params: &Generics) -> Substs { | 362 | pub(crate) fn type_params(generic_params: &Generics) -> Substs { |
370 | Substs( | 363 | Substs( |
371 | generic_params.iter().map(|(idx, p)| Ty::Param { idx, name: p.name.clone().unwrap_or_else(Name::missing) }).collect(), | 364 | generic_params.iter().map(|(id, _)| Ty::Param(id)).collect(), |
372 | ) | 365 | ) |
373 | } | 366 | } |
374 | 367 | ||
375 | /// Return Substs that replace each parameter by a bound variable. | 368 | /// Return Substs that replace each parameter by a bound variable. |
376 | pub(crate) fn bound_vars(generic_params: &Generics) -> Substs { | 369 | pub(crate) fn bound_vars(generic_params: &Generics) -> Substs { |
377 | Substs(generic_params.iter().map(|(idx, _p)| Ty::Bound(idx)).collect()) | 370 | Substs(generic_params.iter().enumerate().map(|(idx, _)| Ty::Bound(idx as u32)).collect()) |
378 | } | 371 | } |
379 | 372 | ||
380 | pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder { | 373 | pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder { |
@@ -422,11 +415,6 @@ impl SubstsBuilder { | |||
422 | self.fill((starting_from..).map(Ty::Bound)) | 415 | self.fill((starting_from..).map(Ty::Bound)) |
423 | } | 416 | } |
424 | 417 | ||
425 | pub fn fill_with_params(self) -> Self { | ||
426 | let start = self.vec.len() as u32; | ||
427 | self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() })) | ||
428 | } | ||
429 | |||
430 | pub fn fill_with_unknown(self) -> Self { | 418 | pub fn fill_with_unknown(self) -> Self { |
431 | self.fill(iter::repeat(Ty::Unknown)) | 419 | self.fill(iter::repeat(Ty::Unknown)) |
432 | } | 420 | } |
@@ -762,13 +750,19 @@ pub trait TypeWalk { | |||
762 | /// Replaces type parameters in this type using the given `Substs`. (So e.g. | 750 | /// Replaces type parameters in this type using the given `Substs`. (So e.g. |
763 | /// if `self` is `&[T]`, where type parameter T has index 0, and the | 751 | /// if `self` is `&[T]`, where type parameter T has index 0, and the |
764 | /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) | 752 | /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) |
765 | fn subst(self, substs: &Substs) -> Self | 753 | // TODO: this should mostly not be used anymore |
754 | fn subst_type_params(self, db: &impl HirDatabase, def: GenericDefId, substs: &Substs) -> Self | ||
766 | where | 755 | where |
767 | Self: Sized, | 756 | Self: Sized, |
768 | { | 757 | { |
758 | let generics = generics(db, def); | ||
769 | self.fold(&mut |ty| match ty { | 759 | self.fold(&mut |ty| match ty { |
770 | Ty::Param { idx, name } => { | 760 | Ty::Param(id) => { |
771 | substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name }) | 761 | if let Some(idx) = generics.param_idx(id) { |
762 | substs.get(idx as usize).cloned().unwrap_or(Ty::Param(id)) | ||
763 | } else { | ||
764 | ty | ||
765 | } | ||
772 | } | 766 | } |
773 | ty => ty, | 767 | ty => ty, |
774 | }) | 768 | }) |
@@ -1042,7 +1036,18 @@ impl HirDisplay for Ty { | |||
1042 | match self { | 1036 | match self { |
1043 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, | 1037 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, |
1044 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, | 1038 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, |
1045 | Ty::Param { name, .. } => write!(f, "{}", name)?, | 1039 | Ty::Param(id) => { |
1040 | let generic_params = f.db.generic_params(id.parent); | ||
1041 | let param_data = &generic_params.types[id.local_id]; | ||
1042 | match param_data.provenance { | ||
1043 | TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => { | ||
1044 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? | ||
1045 | } | ||
1046 | TypeParamProvenance::ArgumentImplTrait => { | ||
1047 | write!(f, "impl TODO")? | ||
1048 | } | ||
1049 | } | ||
1050 | }, | ||
1046 | Ty::Bound(idx) => write!(f, "?{}", idx)?, | 1051 | Ty::Bound(idx) => write!(f, "?{}", idx)?, |
1047 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | 1052 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { |
1048 | match self { | 1053 | match self { |
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 88d962b47..d60b59433 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -30,7 +30,7 @@ use crate::{ | |||
30 | Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs, | 30 | Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs, |
31 | TraitEnvironment, TraitRef, Ty, TypeCtor, | 31 | TraitEnvironment, TraitRef, Ty, TypeCtor, |
32 | }; | 32 | }; |
33 | use hir_expand::name::Name; | 33 | use hir_def::TypeParamId; |
34 | 34 | ||
35 | #[derive(Debug)] | 35 | #[derive(Debug)] |
36 | pub struct TyLoweringContext<'a, DB: HirDatabase> { | 36 | pub struct TyLoweringContext<'a, DB: HirDatabase> { |
@@ -145,7 +145,16 @@ impl Ty { | |||
145 | ImplTraitLoweringMode::Param => { | 145 | ImplTraitLoweringMode::Param => { |
146 | let idx = ctx.impl_trait_counter.get(); | 146 | let idx = ctx.impl_trait_counter.get(); |
147 | ctx.impl_trait_counter.set(idx + 1); | 147 | ctx.impl_trait_counter.set(idx + 1); |
148 | Ty::Param { idx: idx as u32, name: Name::missing() } | 148 | if let Some(def) = ctx.resolver.generic_def() { |
149 | let generics = generics(ctx.db, def); | ||
150 | let param = generics | ||
151 | .iter() | ||
152 | .nth(idx as usize) | ||
153 | .map_or(Ty::Unknown, |(id, _)| Ty::Param(id)); | ||
154 | param | ||
155 | } else { | ||
156 | Ty::Unknown | ||
157 | } | ||
149 | } | 158 | } |
150 | ImplTraitLoweringMode::Variable => { | 159 | ImplTraitLoweringMode::Variable => { |
151 | let idx = ctx.impl_trait_counter.get(); | 160 | let idx = ctx.impl_trait_counter.get(); |
@@ -176,7 +185,7 @@ impl Ty { | |||
176 | fn from_hir_only_param( | 185 | fn from_hir_only_param( |
177 | ctx: &TyLoweringContext<'_, impl HirDatabase>, | 186 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
178 | type_ref: &TypeRef, | 187 | type_ref: &TypeRef, |
179 | ) -> Option<u32> { | 188 | ) -> Option<TypeParamId> { |
180 | let path = match type_ref { | 189 | let path = match type_ref { |
181 | TypeRef::Path(path) => path, | 190 | TypeRef::Path(path) => path, |
182 | _ => return None, | 191 | _ => return None, |
@@ -192,9 +201,7 @@ impl Ty { | |||
192 | _ => return None, | 201 | _ => return None, |
193 | }; | 202 | }; |
194 | if let TypeNs::GenericParam(param_id) = resolution { | 203 | if let TypeNs::GenericParam(param_id) = resolution { |
195 | let generics = generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); | 204 | Some(param_id) |
196 | let idx = generics.param_idx(param_id); | ||
197 | Some(idx) | ||
198 | } else { | 205 | } else { |
199 | None | 206 | None |
200 | } | 207 | } |
@@ -256,20 +263,18 @@ impl Ty { | |||
256 | TypeNs::GenericParam(param_id) => { | 263 | TypeNs::GenericParam(param_id) => { |
257 | let generics = | 264 | let generics = |
258 | generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); | 265 | generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); |
259 | let idx = generics.param_idx(param_id); | ||
260 | match ctx.type_param_mode { | 266 | match ctx.type_param_mode { |
261 | TypeParamLoweringMode::Placeholder => { | 267 | TypeParamLoweringMode::Placeholder => Ty::Param(param_id), |
262 | // FIXME: maybe return name in resolution? | 268 | TypeParamLoweringMode::Variable => { |
263 | let name = generics.param_name(param_id); | 269 | let idx = generics.param_idx(param_id).expect("matching generics"); |
264 | Ty::Param { idx, name } | 270 | Ty::Bound(idx) |
265 | } | 271 | } |
266 | TypeParamLoweringMode::Variable => Ty::Bound(idx), | ||
267 | } | 272 | } |
268 | } | 273 | } |
269 | TypeNs::SelfType(impl_id) => { | 274 | TypeNs::SelfType(impl_id) => { |
270 | let generics = generics(ctx.db, impl_id.into()); | 275 | let generics = generics(ctx.db, impl_id.into()); |
271 | let substs = match ctx.type_param_mode { | 276 | let substs = match ctx.type_param_mode { |
272 | TypeParamLoweringMode::Placeholder => Substs::identity(&generics), | 277 | TypeParamLoweringMode::Placeholder => Substs::type_params(&generics), |
273 | TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), | 278 | TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), |
274 | }; | 279 | }; |
275 | ctx.db.impl_self_ty(impl_id).subst(&substs) | 280 | ctx.db.impl_self_ty(impl_id).subst(&substs) |
@@ -277,7 +282,7 @@ impl Ty { | |||
277 | TypeNs::AdtSelfType(adt) => { | 282 | TypeNs::AdtSelfType(adt) => { |
278 | let generics = generics(ctx.db, adt.into()); | 283 | let generics = generics(ctx.db, adt.into()); |
279 | let substs = match ctx.type_param_mode { | 284 | let substs = match ctx.type_param_mode { |
280 | TypeParamLoweringMode::Placeholder => Substs::identity(&generics), | 285 | TypeParamLoweringMode::Placeholder => Substs::type_params(&generics), |
281 | TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), | 286 | TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), |
282 | }; | 287 | }; |
283 | ctx.db.ty(adt.into()).subst(&substs) | 288 | ctx.db.ty(adt.into()).subst(&substs) |
@@ -319,20 +324,28 @@ impl Ty { | |||
319 | self_ty: Ty, | 324 | self_ty: Ty, |
320 | segment: PathSegment<'_>, | 325 | segment: PathSegment<'_>, |
321 | ) -> Ty { | 326 | ) -> Ty { |
322 | let param_idx = match self_ty { | ||
323 | Ty::Param { idx, .. } if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => idx, | ||
324 | Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => idx, | ||
325 | _ => return Ty::Unknown, // Error: Ambiguous associated type | ||
326 | }; | ||
327 | let def = match ctx.resolver.generic_def() { | 327 | let def = match ctx.resolver.generic_def() { |
328 | Some(def) => def, | 328 | Some(def) => def, |
329 | None => return Ty::Unknown, // this can't actually happen | 329 | None => return Ty::Unknown, // this can't actually happen |
330 | }; | 330 | }; |
331 | let predicates = ctx.db.generic_predicates_for_param(def.into(), param_idx); | 331 | let param_id = match self_ty { |
332 | Ty::Param(id) if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => id, | ||
333 | Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => { | ||
334 | let generics = generics(ctx.db, def); | ||
335 | let param_id = if let Some((id, _)) = generics.iter().nth(idx as usize) { | ||
336 | id | ||
337 | } else { | ||
338 | return Ty::Unknown; | ||
339 | }; | ||
340 | param_id | ||
341 | }, | ||
342 | _ => return Ty::Unknown, // Error: Ambiguous associated type | ||
343 | }; | ||
344 | let predicates = ctx.db.generic_predicates_for_param(param_id); | ||
332 | let traits_from_env = predicates.iter().filter_map(|pred| match pred { | 345 | let traits_from_env = predicates.iter().filter_map(|pred| match pred { |
333 | GenericPredicate::Implemented(tr) => { | 346 | GenericPredicate::Implemented(tr) => { |
334 | if let Ty::Param { idx, .. } = tr.self_ty() { | 347 | if let Ty::Param(id) = tr.self_ty() { |
335 | if *idx == param_idx { | 348 | if *id == param_id { |
336 | return Some(tr.trait_); | 349 | return Some(tr.trait_); |
337 | } | 350 | } |
338 | } | 351 | } |
@@ -530,13 +543,12 @@ impl GenericPredicate { | |||
530 | let generic_def = ctx.resolver.generic_def().expect("generics in scope"); | 543 | let generic_def = ctx.resolver.generic_def().expect("generics in scope"); |
531 | let generics = generics(ctx.db, generic_def); | 544 | let generics = generics(ctx.db, generic_def); |
532 | let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; | 545 | let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; |
533 | let idx = generics.param_idx(param_id); | ||
534 | match ctx.type_param_mode { | 546 | match ctx.type_param_mode { |
535 | TypeParamLoweringMode::Placeholder => { | 547 | TypeParamLoweringMode::Placeholder => Ty::Param(param_id), |
536 | let name = generics.param_name(param_id); | 548 | TypeParamLoweringMode::Variable => { |
537 | Ty::Param { idx, name } | 549 | let idx = generics.param_idx(param_id).expect("matching generics"); |
550 | Ty::Bound(idx) | ||
538 | } | 551 | } |
539 | TypeParamLoweringMode::Variable => Ty::Bound(idx), | ||
540 | } | 552 | } |
541 | } | 553 | } |
542 | }; | 554 | }; |
@@ -599,17 +611,19 @@ pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> PolyFnSig { | |||
599 | pub(crate) fn field_types_query( | 611 | pub(crate) fn field_types_query( |
600 | db: &impl HirDatabase, | 612 | db: &impl HirDatabase, |
601 | variant_id: VariantId, | 613 | variant_id: VariantId, |
602 | ) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { | 614 | ) -> Arc<ArenaMap<LocalStructFieldId, Binders<Ty>>> { |
603 | let var_data = variant_data(db, variant_id); | 615 | let var_data = variant_data(db, variant_id); |
604 | let resolver = match variant_id { | 616 | let (resolver, def): (_, GenericDefId) = match variant_id { |
605 | VariantId::StructId(it) => it.resolver(db), | 617 | VariantId::StructId(it) => (it.resolver(db), it.into()), |
606 | VariantId::UnionId(it) => it.resolver(db), | 618 | VariantId::UnionId(it) => (it.resolver(db), it.into()), |
607 | VariantId::EnumVariantId(it) => it.parent.resolver(db), | 619 | VariantId::EnumVariantId(it) => (it.parent.resolver(db), it.parent.into()), |
608 | }; | 620 | }; |
621 | let generics = generics(db, def); | ||
609 | let mut res = ArenaMap::default(); | 622 | let mut res = ArenaMap::default(); |
610 | let ctx = TyLoweringContext::new(db, &resolver); | 623 | let ctx = TyLoweringContext::new(db, &resolver) |
624 | .with_type_param_mode(TypeParamLoweringMode::Variable); | ||
611 | for (field_id, field_data) in var_data.fields().iter() { | 625 | for (field_id, field_data) in var_data.fields().iter() { |
612 | res.insert(field_id, Ty::from_hir(&ctx, &field_data.type_ref)) | 626 | res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref))) |
613 | } | 627 | } |
614 | Arc::new(res) | 628 | Arc::new(res) |
615 | } | 629 | } |
@@ -624,23 +638,20 @@ pub(crate) fn field_types_query( | |||
624 | /// these are fine: `T: Foo<U::Item>, U: Foo<()>`. | 638 | /// these are fine: `T: Foo<U::Item>, U: Foo<()>`. |
625 | pub(crate) fn generic_predicates_for_param_query( | 639 | pub(crate) fn generic_predicates_for_param_query( |
626 | db: &impl HirDatabase, | 640 | db: &impl HirDatabase, |
627 | def: GenericDefId, | 641 | param_id: TypeParamId, |
628 | param_idx: u32, | ||
629 | ) -> Arc<[GenericPredicate]> { | 642 | ) -> Arc<[GenericPredicate]> { |
630 | let resolver = def.resolver(db); | 643 | let resolver = param_id.parent.resolver(db); |
631 | let ctx = TyLoweringContext::new(db, &resolver); | 644 | let ctx = TyLoweringContext::new(db, &resolver); |
632 | let generics = generics(db, def); | 645 | // let generics = generics(db, def); |
633 | resolver | 646 | resolver |
634 | .where_predicates_in_scope() | 647 | .where_predicates_in_scope() |
635 | // we have to filter out all other predicates *first*, before attempting to lower them | 648 | // we have to filter out all other predicates *first*, before attempting to lower them |
636 | .filter(|pred| match &pred.target { | 649 | .filter(|pred| match &pred.target { |
637 | WherePredicateTarget::TypeRef(type_ref) => { | 650 | WherePredicateTarget::TypeRef(type_ref) => { |
638 | Ty::from_hir_only_param(&ctx, type_ref) == Some(param_idx) | 651 | Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id) |
639 | } | 652 | } |
640 | WherePredicateTarget::TypeParam(local_id) => { | 653 | WherePredicateTarget::TypeParam(local_id) => { |
641 | let param_id = hir_def::TypeParamId { parent: def, local_id: *local_id }; | 654 | *local_id == param_id.local_id |
642 | let idx = generics.param_idx(param_id); | ||
643 | idx == param_idx | ||
644 | } | 655 | } |
645 | }) | 656 | }) |
646 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) | 657 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) |
@@ -650,8 +661,7 @@ pub(crate) fn generic_predicates_for_param_query( | |||
650 | pub(crate) fn generic_predicates_for_param_recover( | 661 | pub(crate) fn generic_predicates_for_param_recover( |
651 | _db: &impl HirDatabase, | 662 | _db: &impl HirDatabase, |
652 | _cycle: &[String], | 663 | _cycle: &[String], |
653 | _def: &GenericDefId, | 664 | _param_id: &TypeParamId, |
654 | _param_idx: &u32, | ||
655 | ) -> Arc<[GenericPredicate]> { | 665 | ) -> Arc<[GenericPredicate]> { |
656 | Arc::new([]) | 666 | Arc::new([]) |
657 | } | 667 | } |
@@ -905,12 +915,12 @@ pub(crate) fn impl_self_ty_recover( | |||
905 | Binders::new(generics.len(), Ty::Unknown) | 915 | Binders::new(generics.len(), Ty::Unknown) |
906 | } | 916 | } |
907 | 917 | ||
908 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { | 918 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { |
909 | let impl_data = db.impl_data(impl_id); | 919 | let impl_data = db.impl_data(impl_id); |
910 | let resolver = impl_id.resolver(db); | 920 | let resolver = impl_id.resolver(db); |
911 | let generics = generics(db, impl_id.into()); | 921 | let ctx = TyLoweringContext::new(db, &resolver) |
912 | let ctx = TyLoweringContext::new(db, &resolver); | 922 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
913 | let self_ty = db.impl_self_ty(impl_id).subst(&Substs::identity(&generics)); | 923 | let self_ty = db.impl_self_ty(impl_id); |
914 | let target_trait = impl_data.target_trait.as_ref()?; | 924 | let target_trait = impl_data.target_trait.as_ref()?; |
915 | TraitRef::from_hir(&ctx, target_trait, Some(self_ty.clone())) | 925 | Some(Binders::new(self_ty.num_binders, TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value.clone()))?)) |
916 | } | 926 | } |
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index eab2149dc..5283bff28 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs | |||
@@ -61,7 +61,7 @@ impl CrateImplBlocks { | |||
61 | for impl_id in module_data.scope.impls() { | 61 | for impl_id in module_data.scope.impls() { |
62 | match db.impl_trait(impl_id) { | 62 | match db.impl_trait(impl_id) { |
63 | Some(tr) => { | 63 | Some(tr) => { |
64 | res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); | 64 | res.impls_by_trait.entry(tr.value.trait_).or_default().push(impl_id); |
65 | } | 65 | } |
66 | None => { | 66 | None => { |
67 | let self_ty = db.impl_self_ty(impl_id); | 67 | let self_ty = db.impl_self_ty(impl_id); |
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 446d12813..1722563aa 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs | |||
@@ -697,7 +697,7 @@ fn test<U, T: Trait<U>>(t: T) { | |||
697 | [71; 72) 't': T | 697 | [71; 72) 't': T |
698 | [77; 96) '{ ...d(); }': () | 698 | [77; 96) '{ ...d(); }': () |
699 | [83; 84) 't': T | 699 | [83; 84) 't': T |
700 | [83; 93) 't.method()': [missing name] | 700 | [83; 93) 't.method()': U |
701 | "### | 701 | "### |
702 | ); | 702 | ); |
703 | } | 703 | } |
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index dc78e83cd..e6f697fa3 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -822,8 +822,7 @@ fn test<T: ApplyL>() { | |||
822 | "#, | 822 | "#, |
823 | ); | 823 | ); |
824 | // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out<T>` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types]. | 824 | // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out<T>` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types]. |
825 | // FIXME: fix type parameter names going missing when going through Chalk | 825 | assert_eq!(t, "ApplyL::Out<T>"); |
826 | assert_eq!(t, "ApplyL::Out<[missing name]>"); | ||
827 | } | 826 | } |
828 | 827 | ||
829 | #[test] | 828 | #[test] |
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index fe9cb556c..6e97f7dd2 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -142,8 +142,9 @@ impl ToChalk for Ty { | |||
142 | let substitution = proj_ty.parameters.to_chalk(db); | 142 | let substitution = proj_ty.parameters.to_chalk(db); |
143 | chalk_ir::AliasTy { associated_ty_id, substitution }.cast().intern() | 143 | chalk_ir::AliasTy { associated_ty_id, substitution }.cast().intern() |
144 | } | 144 | } |
145 | Ty::Param { idx, .. } => { | 145 | Ty::Param(id) => { |
146 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize } | 146 | let interned_id = db.intern_type_param_id(id); |
147 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: interned_id.as_intern_id().as_usize() } | ||
147 | .to_ty::<TypeFamily>() | 148 | .to_ty::<TypeFamily>() |
148 | } | 149 | } |
149 | Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), | 150 | Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), |
@@ -177,7 +178,8 @@ impl ToChalk for Ty { | |||
177 | }, | 178 | }, |
178 | chalk_ir::TyData::Placeholder(idx) => { | 179 | chalk_ir::TyData::Placeholder(idx) => { |
179 | assert_eq!(idx.ui, UniverseIndex::ROOT); | 180 | assert_eq!(idx.ui, UniverseIndex::ROOT); |
180 | Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() } | 181 | let interned_id = crate::db::GlobalTypeParamId::from_intern_id(crate::salsa::InternId::from(idx.idx)); |
182 | Ty::Param(db.lookup_intern_type_param_id(interned_id)) | ||
181 | } | 183 | } |
182 | chalk_ir::TyData::Alias(proj) => { | 184 | chalk_ir::TyData::Alias(proj) => { |
183 | let associated_ty = from_chalk(db, proj.associated_ty_id); | 185 | let associated_ty = from_chalk(db, proj.associated_ty_id); |
@@ -524,7 +526,7 @@ fn convert_where_clauses( | |||
524 | // skip errored predicates completely | 526 | // skip errored predicates completely |
525 | continue; | 527 | continue; |
526 | } | 528 | } |
527 | result.push(pred.clone().subst(substs).to_chalk(db)); | 529 | result.push(pred.clone().subst_type_params(db, def, substs).to_chalk(db)); |
528 | } | 530 | } |
529 | result | 531 | result |
530 | } | 532 | } |
@@ -709,12 +711,12 @@ fn impl_block_datum( | |||
709 | let trait_ref = db | 711 | let trait_ref = db |
710 | .impl_trait(impl_id) | 712 | .impl_trait(impl_id) |
711 | // ImplIds for impls where the trait ref can't be resolved should never reach Chalk | 713 | // ImplIds for impls where the trait ref can't be resolved should never reach Chalk |
712 | .expect("invalid impl passed to Chalk"); | 714 | .expect("invalid impl passed to Chalk") |
715 | .value; | ||
713 | let impl_data = db.impl_data(impl_id); | 716 | let impl_data = db.impl_data(impl_id); |
714 | 717 | ||
715 | let generic_params = generics(db, impl_id.into()); | 718 | let generic_params = generics(db, impl_id.into()); |
716 | let bound_vars = Substs::bound_vars(&generic_params); | 719 | let bound_vars = Substs::bound_vars(&generic_params); |
717 | let trait_ref = trait_ref.subst(&bound_vars); | ||
718 | let trait_ = trait_ref.trait_; | 720 | let trait_ = trait_ref.trait_; |
719 | let impl_type = if impl_id.lookup(db).container.module(db).krate == krate { | 721 | let impl_type = if impl_id.lookup(db).container.module(db).krate == krate { |
720 | chalk_rust_ir::ImplType::Local | 722 | chalk_rust_ir::ImplType::Local |
@@ -789,20 +791,18 @@ fn type_alias_associated_ty_value( | |||
789 | _ => panic!("assoc ty value should be in impl"), | 791 | _ => panic!("assoc ty value should be in impl"), |
790 | }; | 792 | }; |
791 | 793 | ||
792 | let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved | 794 | let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved |
793 | 795 | ||
794 | let assoc_ty = db | 796 | let assoc_ty = db |
795 | .trait_data(trait_ref.trait_) | 797 | .trait_data(trait_ref.trait_) |
796 | .associated_type_by_name(&type_alias_data.name) | 798 | .associated_type_by_name(&type_alias_data.name) |
797 | .expect("assoc ty value should not exist"); // validated when building the impl data as well | 799 | .expect("assoc ty value should not exist"); // validated when building the impl data as well |
798 | let generic_params = generics(db, impl_id.into()); | 800 | let ty = db.ty(type_alias.into()); |
799 | let bound_vars = Substs::bound_vars(&generic_params); | 801 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; |
800 | let ty = db.ty(type_alias.into()).subst(&bound_vars); | ||
801 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; | ||
802 | let value = chalk_rust_ir::AssociatedTyValue { | 802 | let value = chalk_rust_ir::AssociatedTyValue { |
803 | impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db), | 803 | impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db), |
804 | associated_ty_id: assoc_ty.to_chalk(db), | 804 | associated_ty_id: assoc_ty.to_chalk(db), |
805 | value: make_binders(value_bound, bound_vars.len()), | 805 | value: make_binders(value_bound, ty.num_binders), |
806 | }; | 806 | }; |
807 | Arc::new(value) | 807 | Arc::new(value) |
808 | } | 808 | } |
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index 77b7de729..8fa1838bd 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs | |||
@@ -99,23 +99,19 @@ pub(crate) struct Generics { | |||
99 | } | 99 | } |
100 | 100 | ||
101 | impl Generics { | 101 | impl Generics { |
102 | pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = (u32, &'a TypeParamData)> + 'a { | 102 | pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = (TypeParamId, &'a TypeParamData)> + 'a { |
103 | self.parent_generics | 103 | self.parent_generics |
104 | .as_ref() | 104 | .as_ref() |
105 | .into_iter() | 105 | .into_iter() |
106 | .flat_map(|it| it.params.types.iter()) | 106 | .flat_map(|it| it.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))) |
107 | .chain(self.params.types.iter()) | 107 | .chain(self.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: self.def, local_id }, p))) |
108 | .enumerate() | ||
109 | .map(|(i, (_local_id, p))| (i as u32, p)) | ||
110 | } | 108 | } |
111 | 109 | ||
112 | pub(crate) fn iter_parent<'a>(&'a self) -> impl Iterator<Item = (u32, &'a TypeParamData)> + 'a { | 110 | pub(crate) fn iter_parent<'a>(&'a self) -> impl Iterator<Item = (TypeParamId, &'a TypeParamData)> + 'a { |
113 | self.parent_generics | 111 | self.parent_generics |
114 | .as_ref() | 112 | .as_ref() |
115 | .into_iter() | 113 | .into_iter() |
116 | .flat_map(|it| it.params.types.iter()) | 114 | .flat_map(|it| it.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))) |
117 | .enumerate() | ||
118 | .map(|(i, (_local_id, p))| (i as u32, p)) | ||
119 | } | 115 | } |
120 | 116 | ||
121 | pub(crate) fn len(&self) -> usize { | 117 | pub(crate) fn len(&self) -> usize { |
@@ -137,16 +133,11 @@ impl Generics { | |||
137 | (self_params, list_params, impl_trait_params) | 133 | (self_params, list_params, impl_trait_params) |
138 | } | 134 | } |
139 | 135 | ||
140 | pub(crate) fn param_idx(&self, param: TypeParamId) -> u32 { | 136 | pub(crate) fn param_idx(&self, param: TypeParamId) -> Option<u32> { |
141 | self.find_param(param).0 | 137 | Some(self.find_param(param)?.0) |
142 | } | 138 | } |
143 | 139 | ||
144 | pub(crate) fn param_name(&self, param: TypeParamId) -> Name { | 140 | fn find_param(&self, param: TypeParamId) -> Option<(u32, &TypeParamData)> { |
145 | // FIXME make this return Option | ||
146 | self.find_param(param).1.name.clone().unwrap_or_else(Name::missing) | ||
147 | } | ||
148 | |||
149 | fn find_param(&self, param: TypeParamId) -> (u32, &TypeParamData) { | ||
150 | if param.parent == self.def { | 141 | if param.parent == self.def { |
151 | let (idx, (_local_id, data)) = self | 142 | let (idx, (_local_id, data)) = self |
152 | .params | 143 | .params |
@@ -156,9 +147,10 @@ impl Generics { | |||
156 | .find(|(_, (idx, _))| *idx == param.local_id) | 147 | .find(|(_, (idx, _))| *idx == param.local_id) |
157 | .unwrap(); | 148 | .unwrap(); |
158 | let (_total, parent_len, _child) = self.len_split(); | 149 | let (_total, parent_len, _child) = self.len_split(); |
159 | return ((parent_len + idx) as u32, data); | 150 | Some(((parent_len + idx) as u32, data)) |
151 | } else { | ||
152 | self.parent_generics.as_ref().and_then(|g| g.find_param(param)) | ||
160 | } | 153 | } |
161 | self.parent_generics.as_ref().unwrap().find_param(param) | ||
162 | } | 154 | } |
163 | } | 155 | } |
164 | 156 | ||