aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r--crates/ra_hir_ty/src/infer/coerce.rs13
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs36
-rw-r--r--crates/ra_hir_ty/src/infer/pat.rs4
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs47
-rw-r--r--crates/ra_hir_ty/src/infer/unify.rs5
5 files changed, 45 insertions, 60 deletions
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs
index f68a1439f..fb6a51b12 100644
--- a/crates/ra_hir_ty/src/infer/coerce.rs
+++ b/crates/ra_hir_ty/src/infer/coerce.rs
@@ -26,7 +26,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
26 /// Note that it is only possible that one type are coerced to another. 26 /// Note that it is only possible that one type are coerced to another.
27 /// Coercing both types to another least upper bound type is not possible in rustc, 27 /// Coercing both types to another least upper bound type is not possible in rustc,
28 /// which will simply result in "incompatible types" error. 28 /// which will simply result in "incompatible types" error.
29 pub(super) fn coerce_merge_branch<'t>(&mut self, ty1: &Ty, ty2: &Ty) -> Ty { 29 pub(super) fn coerce_merge_branch(&mut self, ty1: &Ty, ty2: &Ty) -> Ty {
30 if self.coerce(ty1, ty2) { 30 if self.coerce(ty1, ty2) {
31 ty2.clone() 31 ty2.clone()
32 } else if self.coerce(ty2, ty1) { 32 } else if self.coerce(ty2, ty1) {
@@ -44,10 +44,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
44 resolver: &Resolver, 44 resolver: &Resolver,
45 ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { 45 ) -> FxHashMap<(TypeCtor, TypeCtor), usize> {
46 let krate = resolver.krate().unwrap(); 46 let krate = resolver.krate().unwrap();
47 let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) { 47 let impls = match db.lang_item(krate, "coerce_unsized".into()) {
48 Some(LangItemTarget::TraitId(trait_)) => { 48 Some(LangItemTarget::TraitId(trait_)) => db.impls_for_trait(krate, trait_),
49 db.impls_for_trait(krate.into(), trait_.into())
50 }
51 _ => return FxHashMap::default(), 49 _ => return FxHashMap::default(),
52 }; 50 };
53 51
@@ -254,15 +252,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
254 let unsize_generic_index = { 252 let unsize_generic_index = {
255 let mut index = None; 253 let mut index = None;
256 let mut multiple_param = false; 254 let mut multiple_param = false;
257 field_tys[last_field_id].value.walk(&mut |ty| match ty { 255 field_tys[last_field_id].value.walk(&mut |ty| {
258 &Ty::Bound(idx) => { 256 if let &Ty::Bound(idx) = ty {
259 if index.is_none() { 257 if index.is_none() {
260 index = Some(idx); 258 index = Some(idx);
261 } else if Some(idx) != index { 259 } else if Some(idx) != index {
262 multiple_param = true; 260 multiple_param = true;
263 } 261 }
264 } 262 }
265 _ => {}
266 }); 263 });
267 264
268 if multiple_param { 265 if multiple_param {
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 39d8bc0ca..9d5f75625 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -35,8 +35,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
35 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, 35 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
36 ); 36 );
37 } 37 }
38 let ty = self.resolve_ty_as_possible(ty); 38 self.resolve_ty_as_possible(ty)
39 ty
40 } 39 }
41 40
42 /// Infer type of expression with possibly implicit coerce to the expected type. 41 /// Infer type of expression with possibly implicit coerce to the expected type.
@@ -127,10 +126,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
127 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, 126 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 },
128 Substs(sig_tys.into()), 127 Substs(sig_tys.into()),
129 ); 128 );
130 let closure_ty = Ty::apply_one( 129 let closure_ty =
131 TypeCtor::Closure { def: self.owner.into(), expr: tgt_expr }, 130 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty);
132 sig_ty,
133 );
134 131
135 // Eagerly try to relate the closure type with the expected 132 // Eagerly try to relate the closure type with the expected
136 // type, otherwise we often won't have enough information to 133 // type, otherwise we often won't have enough information to
@@ -157,15 +154,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
157 }; 154 };
158 self.register_obligations_for_call(&callee_ty); 155 self.register_obligations_for_call(&callee_ty);
159 self.check_call_arguments(args, &param_tys); 156 self.check_call_arguments(args, &param_tys);
160 let ret_ty = self.normalize_associated_types_in(ret_ty); 157 self.normalize_associated_types_in(ret_ty)
161 ret_ty
162 } 158 }
163 Expr::MethodCall { receiver, args, method_name, generic_args } => self 159 Expr::MethodCall { receiver, args, method_name, generic_args } => self
164 .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()), 160 .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()),
165 Expr::Match { expr, arms } => { 161 Expr::Match { expr, arms } => {
166 let input_ty = self.infer_expr(*expr, &Expectation::none()); 162 let input_ty = self.infer_expr(*expr, &Expectation::none());
167 163
168 let mut result_ty = if arms.len() == 0 { 164 let mut result_ty = if arms.is_empty() {
169 Ty::simple(TypeCtor::Never) 165 Ty::simple(TypeCtor::Never)
170 } else { 166 } else {
171 self.table.new_type_var() 167 self.table.new_type_var()
@@ -188,7 +184,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
188 } 184 }
189 Expr::Path(p) => { 185 Expr::Path(p) => {
190 // FIXME this could be more efficient... 186 // FIXME this could be more efficient...
191 let resolver = resolver_for_expr(self.db, self.owner.into(), tgt_expr); 187 let resolver = resolver_for_expr(self.db, self.owner, tgt_expr);
192 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 188 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
193 } 189 }
194 Expr::Continue => Ty::simple(TypeCtor::Never), 190 Expr::Continue => Ty::simple(TypeCtor::Never),
@@ -217,8 +213,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
217 self.unify(&ty, &expected.ty); 213 self.unify(&ty, &expected.ty);
218 214
219 let substs = ty.substs().unwrap_or_else(Substs::empty); 215 let substs = ty.substs().unwrap_or_else(Substs::empty);
220 let field_types = 216 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
221 def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default();
222 let variant_data = def_id.map(|it| variant_data(self.db, it)); 217 let variant_data = def_id.map(|it| variant_data(self.db, it));
223 for (field_idx, field) in fields.iter().enumerate() { 218 for (field_idx, field) in fields.iter().enumerate() {
224 let field_def = 219 let field_def =
@@ -264,7 +259,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
264 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 259 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()),
265 TypeCtor::Adt(AdtId::StructId(s)) => { 260 TypeCtor::Adt(AdtId::StructId(s)) => {
266 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 261 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
267 let field = StructFieldId { parent: s.into(), local_id }.into(); 262 let field = StructFieldId { parent: s.into(), local_id };
268 self.write_field_resolution(tgt_expr, field); 263 self.write_field_resolution(tgt_expr, field);
269 self.db.field_types(s.into())[field.local_id] 264 self.db.field_types(s.into())[field.local_id]
270 .clone() 265 .clone()
@@ -283,14 +278,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
283 } 278 }
284 Expr::Await { expr } => { 279 Expr::Await { expr } => {
285 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 280 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
286 let ty = 281 self.resolve_associated_type(inner_ty, self.resolve_future_future_output())
287 self.resolve_associated_type(inner_ty, self.resolve_future_future_output());
288 ty
289 } 282 }
290 Expr::Try { expr } => { 283 Expr::Try { expr } => {
291 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 284 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
292 let ty = self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok()); 285 self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok())
293 ty
294 } 286 }
295 Expr::Cast { expr, type_ref } => { 287 Expr::Cast { expr, type_ref } => {
296 let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 288 let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
@@ -614,8 +606,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
614 self.unify(&expected_receiver_ty, &actual_receiver_ty); 606 self.unify(&expected_receiver_ty, &actual_receiver_ty);
615 607
616 self.check_call_arguments(args, &param_tys); 608 self.check_call_arguments(args, &param_tys);
617 let ret_ty = self.normalize_associated_types_in(ret_ty); 609 self.normalize_associated_types_in(ret_ty)
618 ret_ty
619 } 610 }
620 611
621 fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) { 612 fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) {
@@ -700,10 +691,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
700 // construct a TraitDef 691 // construct a TraitDef
701 let substs = 692 let substs =
702 a_ty.parameters.prefix(generics(self.db, trait_.into()).len()); 693 a_ty.parameters.prefix(generics(self.db, trait_.into()).len());
703 self.obligations.push(Obligation::Trait(TraitRef { 694 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
704 trait_: trait_.into(),
705 substs,
706 }));
707 } 695 }
708 } 696 }
709 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {} 697 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {}
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index a5dfdf6c4..a495ecbfe 100644
--- a/crates/ra_hir_ty/src/infer/pat.rs
+++ b/crates/ra_hir_ty/src/infer/pat.rs
@@ -28,7 +28,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
28 28
29 let substs = ty.substs().unwrap_or_else(Substs::empty); 29 let substs = ty.substs().unwrap_or_else(Substs::empty);
30 30
31 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); 31 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
32 32
33 for (i, &subpat) in subpats.iter().enumerate() { 33 for (i, &subpat) in subpats.iter().enumerate() {
34 let expected_ty = var_data 34 let expected_ty = var_data
@@ -60,7 +60,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
60 60
61 let substs = ty.substs().unwrap_or_else(Substs::empty); 61 let substs = ty.substs().unwrap_or_else(Substs::empty);
62 62
63 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); 63 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
64 for subpat in subpats { 64 for subpat in subpats {
65 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));
66 let expected_ty = 66 let expected_ty =
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 686ce7a21..471d60342 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -104,8 +104,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
104 let segment = 104 let segment =
105 remaining_segments.last().expect("there should be at least one segment here"); 105 remaining_segments.last().expect("there should be at least one segment here");
106 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 106 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
107 let trait_ref = 107 let trait_ref = TraitRef::from_resolved_path(&ctx, trait_, resolved_segment, None);
108 TraitRef::from_resolved_path(&ctx, trait_.into(), resolved_segment, None);
109 self.resolve_trait_assoc_item(trait_ref, segment, id) 108 self.resolve_trait_assoc_item(trait_ref, segment, id)
110 } 109 }
111 (def, _) => { 110 (def, _) => {
@@ -144,30 +143,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
144 id: ExprOrPatId, 143 id: ExprOrPatId,
145 ) -> Option<(ValueNs, Option<Substs>)> { 144 ) -> Option<(ValueNs, Option<Substs>)> {
146 let trait_ = trait_ref.trait_; 145 let trait_ = trait_ref.trait_;
147 let item = self 146 let item =
148 .db 147 self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| {
149 .trait_data(trait_) 148 match item {
150 .items 149 AssocItemId::FunctionId(func) => {
151 .iter() 150 if segment.name == &self.db.function_data(func).name {
152 .map(|(_name, id)| (*id).into()) 151 Some(AssocItemId::FunctionId(func))
153 .find_map(|item| match item { 152 } else {
154 AssocItemId::FunctionId(func) => { 153 None
155 if segment.name == &self.db.function_data(func).name { 154 }
156 Some(AssocItemId::FunctionId(func))
157 } else {
158 None
159 } 155 }
160 }
161 156
162 AssocItemId::ConstId(konst) => { 157 AssocItemId::ConstId(konst) => {
163 if self.db.const_data(konst).name.as_ref().map_or(false, |n| n == segment.name) 158 if self
164 { 159 .db
165 Some(AssocItemId::ConstId(konst)) 160 .const_data(konst)
166 } else { 161 .name
167 None 162 .as_ref()
163 .map_or(false, |n| n == segment.name)
164 {
165 Some(AssocItemId::ConstId(konst))
166 } else {
167 None
168 }
168 } 169 }
170 AssocItemId::TypeAliasId(_) => None,
169 } 171 }
170 AssocItemId::TypeAliasId(_) => None,
171 })?; 172 })?;
172 let def = match item { 173 let def = match item {
173 AssocItemId::FunctionId(f) => ValueNs::FunctionId(f), 174 AssocItemId::FunctionId(f) => ValueNs::FunctionId(f),
@@ -233,7 +234,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
233 AssocContainerId::ContainerId(_) => None, 234 AssocContainerId::ContainerId(_) => None,
234 }; 235 };
235 236
236 self.write_assoc_resolution(id, item.into()); 237 self.write_assoc_resolution(id, item);
237 Some((def, substs)) 238 Some((def, substs))
238 }, 239 },
239 ) 240 )
diff --git a/crates/ra_hir_ty/src/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs
index 1dc842f40..9c7996572 100644
--- a/crates/ra_hir_ty/src/infer/unify.rs
+++ b/crates/ra_hir_ty/src/infer/unify.rs
@@ -140,13 +140,12 @@ where
140impl<T> Canonicalized<T> { 140impl<T> Canonicalized<T> {
141 pub fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 141 pub fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
142 ty.walk_mut_binders( 142 ty.walk_mut_binders(
143 &mut |ty, binders| match ty { 143 &mut |ty, binders| {
144 &mut Ty::Bound(idx) => { 144 if let &mut Ty::Bound(idx) = ty {
145 if idx as usize >= binders && (idx as usize - binders) < self.free_vars.len() { 145 if idx as usize >= binders && (idx as usize - binders) < self.free_vars.len() {
146 *ty = Ty::Infer(self.free_vars[idx as usize - binders]); 146 *ty = Ty::Infer(self.free_vars[idx as usize - binders]);
147 } 147 }
148 } 148 }
149 _ => {}
150 }, 149 },
151 0, 150 0,
152 ); 151 );