diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r-- | crates/ra_hir_ty/src/infer/coerce.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 36 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/pat.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/path.rs | 47 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/unify.rs | 5 |
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, ¶m_tys); | 156 | self.check_call_arguments(args, ¶m_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, ¶m_tys); | 608 | self.check_call_arguments(args, ¶m_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 | |||
140 | impl<T> Canonicalized<T> { | 140 | impl<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 | ); |