diff options
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 48 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 9 |
3 files changed, 43 insertions, 52 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index e8ae33ead..6cc5dbc6f 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -462,7 +462,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
462 | let mut resolved = | 462 | let mut resolved = |
463 | if remaining_index.is_none() { def.take_values()? } else { def.take_types()? }; | 463 | if remaining_index.is_none() { def.take_values()? } else { def.take_types()? }; |
464 | 464 | ||
465 | let remaining_index = remaining_index.unwrap_or(path.segments.len()); | 465 | let remaining_index = remaining_index.unwrap_or_else(|| path.segments.len()); |
466 | let mut actual_def_ty: Option<Ty> = None; | 466 | let mut actual_def_ty: Option<Ty> = None; |
467 | 467 | ||
468 | let krate = resolver.krate()?; | 468 | let krate = resolver.krate()?; |
@@ -539,7 +539,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
539 | } | 539 | } |
540 | })?; | 540 | })?; |
541 | 541 | ||
542 | resolved = Resolution::Def(item.into()); | 542 | resolved = Resolution::Def(item); |
543 | } | 543 | } |
544 | 544 | ||
545 | match resolved { | 545 | match resolved { |
@@ -762,7 +762,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
762 | _ => &Ty::Unknown, | 762 | _ => &Ty::Unknown, |
763 | }; | 763 | }; |
764 | let subty = self.infer_pat(*pat, expectation, default_bm); | 764 | let subty = self.infer_pat(*pat, expectation, default_bm); |
765 | Ty::apply_one(TypeCtor::Ref(*mutability), subty.into()) | 765 | Ty::apply_one(TypeCtor::Ref(*mutability), subty) |
766 | } | 766 | } |
767 | Pat::TupleStruct { path: ref p, args: ref subpats } => { | 767 | Pat::TupleStruct { path: ref p, args: ref subpats } => { |
768 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) | 768 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) |
@@ -790,7 +790,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
790 | 790 | ||
791 | let bound_ty = match mode { | 791 | let bound_ty = match mode { |
792 | BindingMode::Ref(mutability) => { | 792 | BindingMode::Ref(mutability) => { |
793 | Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone().into()) | 793 | Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) |
794 | } | 794 | } |
795 | BindingMode::Move => inner_ty.clone(), | 795 | BindingMode::Move => inner_ty.clone(), |
796 | }; | 796 | }; |
@@ -848,28 +848,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
848 | } | 848 | } |
849 | 849 | ||
850 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 850 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
851 | match callable_ty { | 851 | if let Ty::Apply(a_ty) = callable_ty { |
852 | Ty::Apply(a_ty) => match a_ty.ctor { | 852 | if let TypeCtor::FnDef(def) = a_ty.ctor { |
853 | TypeCtor::FnDef(def) => { | 853 | // add obligation for trait implementation, if this is a trait method |
854 | // add obligation for trait implementation, if this is a trait method | 854 | // FIXME also register obligations from where clauses from the trait or impl and method |
855 | // FIXME also register obligations from where clauses from the trait or impl and method | 855 | match def { |
856 | match def { | 856 | CallableDef::Function(f) => { |
857 | CallableDef::Function(f) => { | 857 | if let Some(trait_) = f.parent_trait(self.db) { |
858 | if let Some(trait_) = f.parent_trait(self.db) { | 858 | // construct a TraitDef |
859 | // construct a TraitDef | 859 | let substs = a_ty.parameters.prefix( |
860 | let substs = a_ty.parameters.prefix( | 860 | trait_.generic_params(self.db).count_params_including_parent(), |
861 | trait_.generic_params(self.db).count_params_including_parent(), | 861 | ); |
862 | ); | 862 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
863 | self.obligations | ||
864 | .push(Obligation::Trait(TraitRef { trait_, substs })); | ||
865 | } | ||
866 | } | 863 | } |
867 | CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {} | ||
868 | } | 864 | } |
865 | CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {} | ||
869 | } | 866 | } |
870 | _ => {} | 867 | } |
871 | }, | ||
872 | _ => {} | ||
873 | } | 868 | } |
874 | } | 869 | } |
875 | 870 | ||
@@ -951,6 +946,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
951 | then_ty | 946 | then_ty |
952 | } | 947 | } |
953 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), | 948 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), |
949 | Expr::TryBlock { body } => { | ||
950 | let _inner = self.infer_expr(*body, expected); | ||
951 | // FIXME should be std::result::Result<{inner}, _> | ||
952 | Ty::Unknown | ||
953 | } | ||
954 | Expr::Loop { body } => { | 954 | Expr::Loop { body } => { |
955 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 955 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
956 | // FIXME handle break with value | 956 | // FIXME handle break with value |
@@ -1049,7 +1049,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1049 | Expr::StructLit { path, fields, spread } => { | 1049 | Expr::StructLit { path, fields, spread } => { |
1050 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 1050 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
1051 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 1051 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
1052 | for (field_idx, field) in fields.into_iter().enumerate() { | 1052 | for (field_idx, field) in fields.iter().enumerate() { |
1053 | let field_ty = def_id | 1053 | let field_ty = def_id |
1054 | .and_then(|it| match it.field(self.db, &field.name) { | 1054 | .and_then(|it| match it.field(self.db, &field.name) { |
1055 | Some(field) => Some(field), | 1055 | Some(field) => Some(field), |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 34817a5ec..646e58aa9 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -192,23 +192,20 @@ fn iterate_trait_method_candidates<T>( | |||
192 | // iteration | 192 | // iteration |
193 | let mut known_implemented = false; | 193 | let mut known_implemented = false; |
194 | for item in data.items() { | 194 | for item in data.items() { |
195 | match item { | 195 | if let TraitItem::Function(m) = *item { |
196 | &TraitItem::Function(m) => { | 196 | let sig = m.signature(db); |
197 | let sig = m.signature(db); | 197 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { |
198 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { | 198 | if !known_implemented { |
199 | if !known_implemented { | 199 | let trait_ref = canonical_trait_ref(db, t, ty.clone()); |
200 | let trait_ref = canonical_trait_ref(db, t, ty.clone()); | 200 | if db.implements(krate, trait_ref).is_none() { |
201 | if db.implements(krate, trait_ref).is_none() { | 201 | continue 'traits; |
202 | continue 'traits; | ||
203 | } | ||
204 | } | ||
205 | known_implemented = true; | ||
206 | if let Some(result) = callback(&ty.value, m) { | ||
207 | return Some(result); | ||
208 | } | 202 | } |
209 | } | 203 | } |
204 | known_implemented = true; | ||
205 | if let Some(result) = callback(&ty.value, m) { | ||
206 | return Some(result); | ||
207 | } | ||
210 | } | 208 | } |
211 | _ => {} | ||
212 | } | 209 | } |
213 | } | 210 | } |
214 | } | 211 | } |
@@ -230,16 +227,13 @@ fn iterate_inherent_methods<T>( | |||
230 | 227 | ||
231 | for impl_block in impls.lookup_impl_blocks(&ty.value) { | 228 | for impl_block in impls.lookup_impl_blocks(&ty.value) { |
232 | for item in impl_block.items(db) { | 229 | for item in impl_block.items(db) { |
233 | match item { | 230 | if let ImplItem::Method(f) = item { |
234 | ImplItem::Method(f) => { | 231 | let sig = f.signature(db); |
235 | let sig = f.signature(db); | 232 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { |
236 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { | 233 | if let Some(result) = callback(&ty.value, f) { |
237 | if let Some(result) = callback(&ty.value, f) { | 234 | return Some(result); |
238 | return Some(result); | ||
239 | } | ||
240 | } | 235 | } |
241 | } | 236 | } |
242 | _ => {} | ||
243 | } | 237 | } |
244 | } | 238 | } |
245 | } | 239 | } |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 78440b258..1e4806db0 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -211,13 +211,10 @@ fn convert_where_clauses( | |||
211 | // anyway), otherwise Chalk can easily get into slow situations | 211 | // anyway), otherwise Chalk can easily get into slow situations |
212 | return vec![pred.clone().subst(substs).to_chalk(db)]; | 212 | return vec![pred.clone().subst(substs).to_chalk(db)]; |
213 | } | 213 | } |
214 | match pred { | 214 | if let GenericPredicate::Implemented(trait_ref) = pred { |
215 | GenericPredicate::Implemented(trait_ref) => { | 215 | if blacklisted_trait(db, trait_ref.trait_) { |
216 | if blacklisted_trait(db, trait_ref.trait_) { | 216 | continue; |
217 | continue; | ||
218 | } | ||
219 | } | 217 | } |
220 | _ => {} | ||
221 | } | 218 | } |
222 | result.push(pred.clone().subst(substs).to_chalk(db)); | 219 | result.push(pred.clone().subst(substs).to_chalk(db)); |
223 | } | 220 | } |