diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 180 |
1 files changed, 147 insertions, 33 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 8d6493887..b9a48929d 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -37,6 +37,7 @@ use crate::{ | |||
37 | type_ref::{TypeRef, Mutability}, | 37 | type_ref::{TypeRef, Mutability}, |
38 | name::KnownName, | 38 | name::KnownName, |
39 | expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat}, | 39 | expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat}, |
40 | generics::Generics, | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | /// The ID of a type variable. | 43 | /// The ID of a type variable. |
@@ -151,10 +152,14 @@ impl Expectation { | |||
151 | } | 152 | } |
152 | } | 153 | } |
153 | 154 | ||
155 | /// A list of substitutions for generic parameters. | ||
156 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
157 | pub struct Substs(Arc<[Ty]>); | ||
158 | |||
154 | /// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs). | 159 | /// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs). |
155 | /// | 160 | /// |
156 | /// This should be cheap to clone. | 161 | /// This should be cheap to clone. |
157 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 162 | #[derive(Clone, PartialEq, Eq, Debug)] |
158 | pub enum Ty { | 163 | pub enum Ty { |
159 | /// The primitive boolean type. Written as `bool`. | 164 | /// The primitive boolean type. Written as `bool`. |
160 | Bool, | 165 | Bool, |
@@ -175,7 +180,8 @@ pub enum Ty { | |||
175 | def_id: DefId, | 180 | def_id: DefId, |
176 | /// The name, for displaying. | 181 | /// The name, for displaying. |
177 | name: Name, | 182 | name: Name, |
178 | // later we'll need generic substitutions here | 183 | /// Substitutions for the generic parameters of the type. |
184 | substs: Substs, | ||
179 | }, | 185 | }, |
180 | 186 | ||
181 | /// The pointee of a string slice. Written as `str`. | 187 | /// The pointee of a string slice. Written as `str`. |
@@ -234,9 +240,14 @@ pub enum Ty { | |||
234 | 240 | ||
235 | // Opaque (`impl Trait`) type found in a return type. | 241 | // Opaque (`impl Trait`) type found in a return type. |
236 | // Opaque(DefId, Substs), | 242 | // Opaque(DefId, Substs), |
243 | /// A type parameter; for example, `T` in `fn f<T>(x: T) {} | ||
244 | Param { | ||
245 | /// The index of the parameter. | ||
246 | idx: u32, | ||
247 | /// The name of the parameter, for displaying. | ||
248 | name: Name, | ||
249 | }, | ||
237 | 250 | ||
238 | // A type parameter; for example, `T` in `fn f<T>(x: T) {} | ||
239 | // Param(ParamTy), | ||
240 | /// A type variable used during type checking. Not to be confused with a | 251 | /// A type variable used during type checking. Not to be confused with a |
241 | /// type parameter. | 252 | /// type parameter. |
242 | Infer(InferTy), | 253 | Infer(InferTy), |
@@ -250,7 +261,7 @@ pub enum Ty { | |||
250 | } | 261 | } |
251 | 262 | ||
252 | /// A function signature. | 263 | /// A function signature. |
253 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 264 | #[derive(Clone, PartialEq, Eq, Debug)] |
254 | pub struct FnSig { | 265 | pub struct FnSig { |
255 | input: Vec<Ty>, | 266 | input: Vec<Ty>, |
256 | output: Ty, | 267 | output: Ty, |
@@ -261,6 +272,7 @@ impl Ty { | |||
261 | db: &impl HirDatabase, | 272 | db: &impl HirDatabase, |
262 | module: &Module, | 273 | module: &Module, |
263 | impl_block: Option<&ImplBlock>, | 274 | impl_block: Option<&ImplBlock>, |
275 | generics: &Generics, | ||
264 | type_ref: &TypeRef, | 276 | type_ref: &TypeRef, |
265 | ) -> Self { | 277 | ) -> Self { |
266 | match type_ref { | 278 | match type_ref { |
@@ -268,32 +280,32 @@ impl Ty { | |||
268 | TypeRef::Tuple(inner) => { | 280 | TypeRef::Tuple(inner) => { |
269 | let inner_tys = inner | 281 | let inner_tys = inner |
270 | .iter() | 282 | .iter() |
271 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) | 283 | .map(|tr| Ty::from_hir(db, module, impl_block, generics, tr)) |
272 | .collect::<Vec<_>>(); | 284 | .collect::<Vec<_>>(); |
273 | Ty::Tuple(inner_tys.into()) | 285 | Ty::Tuple(inner_tys.into()) |
274 | } | 286 | } |
275 | TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, path), | 287 | TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, generics, path), |
276 | TypeRef::RawPtr(inner, mutability) => { | 288 | TypeRef::RawPtr(inner, mutability) => { |
277 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); | 289 | let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); |
278 | Ty::RawPtr(Arc::new(inner_ty), *mutability) | 290 | Ty::RawPtr(Arc::new(inner_ty), *mutability) |
279 | } | 291 | } |
280 | TypeRef::Array(inner) => { | 292 | TypeRef::Array(inner) => { |
281 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); | 293 | let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); |
282 | Ty::Array(Arc::new(inner_ty)) | 294 | Ty::Array(Arc::new(inner_ty)) |
283 | } | 295 | } |
284 | TypeRef::Slice(inner) => { | 296 | TypeRef::Slice(inner) => { |
285 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); | 297 | let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); |
286 | Ty::Slice(Arc::new(inner_ty)) | 298 | Ty::Slice(Arc::new(inner_ty)) |
287 | } | 299 | } |
288 | TypeRef::Reference(inner, mutability) => { | 300 | TypeRef::Reference(inner, mutability) => { |
289 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); | 301 | let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); |
290 | Ty::Ref(Arc::new(inner_ty), *mutability) | 302 | Ty::Ref(Arc::new(inner_ty), *mutability) |
291 | } | 303 | } |
292 | TypeRef::Placeholder => Ty::Unknown, | 304 | TypeRef::Placeholder => Ty::Unknown, |
293 | TypeRef::Fn(params) => { | 305 | TypeRef::Fn(params) => { |
294 | let mut inner_tys = params | 306 | let mut inner_tys = params |
295 | .iter() | 307 | .iter() |
296 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) | 308 | .map(|tr| Ty::from_hir(db, module, impl_block, generics, tr)) |
297 | .collect::<Vec<_>>(); | 309 | .collect::<Vec<_>>(); |
298 | let return_ty = inner_tys | 310 | let return_ty = inner_tys |
299 | .pop() | 311 | .pop() |
@@ -312,15 +324,19 @@ impl Ty { | |||
312 | db: &impl HirDatabase, | 324 | db: &impl HirDatabase, |
313 | module: &Module, | 325 | module: &Module, |
314 | impl_block: Option<&ImplBlock>, | 326 | impl_block: Option<&ImplBlock>, |
327 | generics: &Generics, | ||
315 | type_ref: Option<&TypeRef>, | 328 | type_ref: Option<&TypeRef>, |
316 | ) -> Self { | 329 | ) -> Self { |
317 | type_ref.map_or(Ty::Unknown, |t| Ty::from_hir(db, module, impl_block, t)) | 330 | type_ref.map_or(Ty::Unknown, |t| { |
331 | Ty::from_hir(db, module, impl_block, generics, t) | ||
332 | }) | ||
318 | } | 333 | } |
319 | 334 | ||
320 | pub(crate) fn from_hir_path( | 335 | pub(crate) fn from_hir_path( |
321 | db: &impl HirDatabase, | 336 | db: &impl HirDatabase, |
322 | module: &Module, | 337 | module: &Module, |
323 | impl_block: Option<&ImplBlock>, | 338 | impl_block: Option<&ImplBlock>, |
339 | generics: &Generics, | ||
324 | path: &Path, | 340 | path: &Path, |
325 | ) -> Self { | 341 | ) -> Self { |
326 | if let Some(name) = path.as_ident() { | 342 | if let Some(name) = path.as_ident() { |
@@ -329,7 +345,15 @@ impl Ty { | |||
329 | } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { | 345 | } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { |
330 | return Ty::Float(float_ty); | 346 | return Ty::Float(float_ty); |
331 | } else if name.as_known_name() == Some(KnownName::SelfType) { | 347 | } else if name.as_known_name() == Some(KnownName::SelfType) { |
332 | return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); | 348 | // TODO pass the impl block's generics? |
349 | let generics = &Generics::default(); | ||
350 | return Ty::from_hir_opt( | ||
351 | db, | ||
352 | module, | ||
353 | None, | ||
354 | generics, | ||
355 | impl_block.map(|i| i.target_type()), | ||
356 | ); | ||
333 | } else if let Some(known) = name.as_known_name() { | 357 | } else if let Some(known) = name.as_known_name() { |
334 | match known { | 358 | match known { |
335 | KnownName::Bool => return Ty::Bool, | 359 | KnownName::Bool => return Ty::Bool, |
@@ -337,6 +361,11 @@ impl Ty { | |||
337 | KnownName::Str => return Ty::Str, | 361 | KnownName::Str => return Ty::Str, |
338 | _ => {} | 362 | _ => {} |
339 | } | 363 | } |
364 | } else if let Some(generic_param) = generics.find_by_name(&name) { | ||
365 | return Ty::Param { | ||
366 | idx: generic_param.idx, | ||
367 | name: generic_param.name.clone(), | ||
368 | }; | ||
340 | } | 369 | } |
341 | } | 370 | } |
342 | 371 | ||
@@ -374,7 +403,14 @@ impl Ty { | |||
374 | } | 403 | } |
375 | sig_mut.output.walk_mut(f); | 404 | sig_mut.output.walk_mut(f); |
376 | } | 405 | } |
377 | Ty::Adt { .. } => {} // need to walk type parameters later | 406 | Ty::Adt { substs, .. } => { |
407 | // Without an Arc::make_mut_slice, we can't avoid the clone here: | ||
408 | let mut v: Vec<_> = substs.0.iter().cloned().collect(); | ||
409 | for t in &mut v { | ||
410 | t.walk_mut(f); | ||
411 | } | ||
412 | substs.0 = v.into(); | ||
413 | } | ||
378 | _ => {} | 414 | _ => {} |
379 | } | 415 | } |
380 | } | 416 | } |
@@ -394,6 +430,32 @@ impl Ty { | |||
394 | _ => None, | 430 | _ => None, |
395 | } | 431 | } |
396 | } | 432 | } |
433 | |||
434 | /// Replaces type parameters in this type using the given `Substs`. (So e.g. | ||
435 | /// if `self` is `&[T]`, where type parameter T has index 0, and the | ||
436 | /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) | ||
437 | pub fn subst(self, substs: &Substs) -> Ty { | ||
438 | self.fold(&mut |ty| match ty { | ||
439 | Ty::Param { idx, name } => { | ||
440 | if (idx as usize) < substs.0.len() { | ||
441 | substs.0[idx as usize].clone() | ||
442 | } else { | ||
443 | // TODO it's yet unclear to me whether we need to shift the indices here | ||
444 | Ty::Param { idx, name } | ||
445 | } | ||
446 | } | ||
447 | ty => ty, | ||
448 | }) | ||
449 | } | ||
450 | |||
451 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | ||
452 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | ||
453 | fn substs(&self) -> Option<Substs> { | ||
454 | match self { | ||
455 | Ty::Adt { substs, .. } => Some(substs.clone()), | ||
456 | _ => None, | ||
457 | } | ||
458 | } | ||
397 | } | 459 | } |
398 | 460 | ||
399 | impl fmt::Display for Ty { | 461 | impl fmt::Display for Ty { |
@@ -425,7 +487,17 @@ impl fmt::Display for Ty { | |||
425 | .to_fmt(f)?; | 487 | .to_fmt(f)?; |
426 | write!(f, " -> {}", sig.output) | 488 | write!(f, " -> {}", sig.output) |
427 | } | 489 | } |
428 | Ty::Adt { name, .. } => write!(f, "{}", name), | 490 | Ty::Adt { name, substs, .. } => { |
491 | write!(f, "{}", name)?; | ||
492 | if substs.0.len() > 0 { | ||
493 | join(substs.0.iter()) | ||
494 | .surround_with("<", ">") | ||
495 | .separator(", ") | ||
496 | .to_fmt(f)?; | ||
497 | } | ||
498 | Ok(()) | ||
499 | } | ||
500 | Ty::Param { name, .. } => write!(f, "{}", name), | ||
429 | Ty::Unknown => write!(f, "[unknown]"), | 501 | Ty::Unknown => write!(f, "[unknown]"), |
430 | Ty::Infer(..) => write!(f, "_"), | 502 | Ty::Infer(..) => write!(f, "_"), |
431 | } | 503 | } |
@@ -440,28 +512,49 @@ fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty { | |||
440 | let signature = f.signature(db); | 512 | let signature = f.signature(db); |
441 | let module = f.module(db); | 513 | let module = f.module(db); |
442 | let impl_block = f.impl_block(db); | 514 | let impl_block = f.impl_block(db); |
443 | // TODO we ignore type parameters for now | 515 | let generics = f.generics(db); |
444 | let input = signature | 516 | let input = signature |
445 | .params() | 517 | .params() |
446 | .iter() | 518 | .iter() |
447 | .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr)) | 519 | .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), &generics, tr)) |
448 | .collect::<Vec<_>>(); | 520 | .collect::<Vec<_>>(); |
449 | let output = Ty::from_hir(db, &module, impl_block.as_ref(), signature.ret_type()); | 521 | let output = Ty::from_hir( |
522 | db, | ||
523 | &module, | ||
524 | impl_block.as_ref(), | ||
525 | &generics, | ||
526 | signature.ret_type(), | ||
527 | ); | ||
450 | let sig = FnSig { input, output }; | 528 | let sig = FnSig { input, output }; |
451 | Ty::FnPtr(Arc::new(sig)) | 529 | Ty::FnPtr(Arc::new(sig)) |
452 | } | 530 | } |
453 | 531 | ||
532 | fn make_substs(generics: &Generics) -> Substs { | ||
533 | Substs( | ||
534 | generics | ||
535 | .params | ||
536 | .iter() | ||
537 | .map(|_p| Ty::Unknown) | ||
538 | .collect::<Vec<_>>() | ||
539 | .into(), | ||
540 | ) | ||
541 | } | ||
542 | |||
454 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { | 543 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { |
544 | let generics = s.generics(db); | ||
455 | Ty::Adt { | 545 | Ty::Adt { |
456 | def_id: s.def_id(), | 546 | def_id: s.def_id(), |
457 | name: s.name(db).unwrap_or_else(Name::missing), | 547 | name: s.name(db).unwrap_or_else(Name::missing), |
548 | substs: make_substs(&generics), | ||
458 | } | 549 | } |
459 | } | 550 | } |
460 | 551 | ||
461 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { | 552 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { |
553 | let generics = s.generics(db); | ||
462 | Ty::Adt { | 554 | Ty::Adt { |
463 | def_id: s.def_id(), | 555 | def_id: s.def_id(), |
464 | name: s.name(db).unwrap_or_else(Name::missing), | 556 | name: s.name(db).unwrap_or_else(Name::missing), |
557 | substs: make_substs(&generics), | ||
465 | } | 558 | } |
466 | } | 559 | } |
467 | 560 | ||
@@ -506,8 +599,15 @@ pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) | |||
506 | }; | 599 | }; |
507 | let module = def_id.module(db); | 600 | let module = def_id.module(db); |
508 | let impl_block = def_id.impl_block(db); | 601 | let impl_block = def_id.impl_block(db); |
602 | let generics = db.generics(def_id); | ||
509 | let type_ref = variant_data.get_field_type_ref(&field)?; | 603 | let type_ref = variant_data.get_field_type_ref(&field)?; |
510 | Some(Ty::from_hir(db, &module, impl_block.as_ref(), &type_ref)) | 604 | Some(Ty::from_hir( |
605 | db, | ||
606 | &module, | ||
607 | impl_block.as_ref(), | ||
608 | &generics, | ||
609 | &type_ref, | ||
610 | )) | ||
511 | } | 611 | } |
512 | 612 | ||
513 | /// The result of type inference: A mapping from expressions and patterns to types. | 613 | /// The result of type inference: A mapping from expressions and patterns to types. |
@@ -684,8 +784,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
684 | self.type_of_pat.insert(pat, ty); | 784 | self.type_of_pat.insert(pat, ty); |
685 | } | 785 | } |
686 | 786 | ||
687 | fn make_ty(&self, type_ref: &TypeRef) -> Ty { | 787 | fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { |
688 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref) | 788 | // TODO provide generics of function |
789 | let generics = Generics::default(); | ||
790 | let ty = Ty::from_hir( | ||
791 | self.db, | ||
792 | &self.module, | ||
793 | self.impl_block.as_ref(), | ||
794 | &generics, | ||
795 | type_ref, | ||
796 | ); | ||
797 | let ty = self.insert_type_vars(ty); | ||
798 | ty | ||
689 | } | 799 | } |
690 | 800 | ||
691 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | 801 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { |
@@ -848,7 +958,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
848 | Some(ty) | 958 | Some(ty) |
849 | } | 959 | } |
850 | 960 | ||
851 | fn resolve_variant(&self, path: Option<&Path>) -> (Ty, Option<DefId>) { | 961 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<DefId>) { |
852 | let path = if let Some(path) = path { | 962 | let path = if let Some(path) = path { |
853 | path | 963 | path |
854 | } else { | 964 | } else { |
@@ -862,10 +972,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
862 | match def_id.resolve(self.db) { | 972 | match def_id.resolve(self.db) { |
863 | Def::Struct(s) => { | 973 | Def::Struct(s) => { |
864 | let ty = type_for_struct(self.db, s); | 974 | let ty = type_for_struct(self.db, s); |
975 | let ty = self.insert_type_vars(ty); | ||
865 | (ty, Some(def_id)) | 976 | (ty, Some(def_id)) |
866 | } | 977 | } |
867 | Def::EnumVariant(ev) => { | 978 | Def::EnumVariant(ev) => { |
868 | let ty = type_for_enum_variant(self.db, ev); | 979 | let ty = type_for_enum_variant(self.db, ev); |
980 | let ty = self.insert_type_vars(ty); | ||
869 | (ty, Some(def_id)) | 981 | (ty, Some(def_id)) |
870 | } | 982 | } |
871 | _ => (Ty::Unknown, None), | 983 | _ => (Ty::Unknown, None), |
@@ -1155,11 +1267,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1155 | spread, | 1267 | spread, |
1156 | } => { | 1268 | } => { |
1157 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 1269 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
1270 | let substs = ty.substs().expect("adt should have substs"); | ||
1158 | for field in fields { | 1271 | for field in fields { |
1159 | let field_ty = if let Some(def_id) = def_id { | 1272 | let field_ty = if let Some(def_id) = def_id { |
1160 | self.db | 1273 | self.db |
1161 | .type_for_field(def_id, field.name.clone()) | 1274 | .type_for_field(def_id, field.name.clone()) |
1162 | .unwrap_or(Ty::Unknown) | 1275 | .unwrap_or(Ty::Unknown) |
1276 | .subst(&substs) | ||
1163 | } else { | 1277 | } else { |
1164 | Ty::Unknown | 1278 | Ty::Unknown |
1165 | }; | 1279 | }; |
@@ -1180,7 +1294,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1180 | let i = name.to_string().parse::<usize>().ok(); | 1294 | let i = name.to_string().parse::<usize>().ok(); |
1181 | i.and_then(|i| fields.get(i).cloned()) | 1295 | i.and_then(|i| fields.get(i).cloned()) |
1182 | } | 1296 | } |
1183 | Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, name.clone()), | 1297 | Ty::Adt { |
1298 | def_id, ref substs, .. | ||
1299 | } => self | ||
1300 | .db | ||
1301 | .type_for_field(def_id, name.clone()) | ||
1302 | .map(|ty| ty.subst(substs)), | ||
1184 | _ => None, | 1303 | _ => None, |
1185 | }) | 1304 | }) |
1186 | .unwrap_or(Ty::Unknown); | 1305 | .unwrap_or(Ty::Unknown); |
@@ -1193,7 +1312,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1193 | Expr::Cast { expr, type_ref } => { | 1312 | Expr::Cast { expr, type_ref } => { |
1194 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); | 1313 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1195 | let cast_ty = self.make_ty(type_ref); | 1314 | let cast_ty = self.make_ty(type_ref); |
1196 | let cast_ty = self.insert_type_vars(cast_ty); | ||
1197 | // TODO check the cast... | 1315 | // TODO check the cast... |
1198 | cast_ty | 1316 | cast_ty |
1199 | } | 1317 | } |
@@ -1305,12 +1423,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1305 | type_ref, | 1423 | type_ref, |
1306 | initializer, | 1424 | initializer, |
1307 | } => { | 1425 | } => { |
1308 | let decl_ty = Ty::from_hir_opt( | 1426 | let decl_ty = type_ref |
1309 | self.db, | 1427 | .as_ref() |
1310 | &self.module, | 1428 | .map(|tr| self.make_ty(tr)) |
1311 | self.impl_block.as_ref(), | 1429 | .unwrap_or(Ty::Unknown); |
1312 | type_ref.as_ref(), | ||
1313 | ); | ||
1314 | let decl_ty = self.insert_type_vars(decl_ty); | 1430 | let decl_ty = self.insert_type_vars(decl_ty); |
1315 | let ty = if let Some(expr) = initializer { | 1431 | let ty = if let Some(expr) = initializer { |
1316 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); | 1432 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); |
@@ -1338,13 +1454,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1338 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 1454 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
1339 | for (type_ref, pat) in signature.params().iter().zip(body.params()) { | 1455 | for (type_ref, pat) in signature.params().iter().zip(body.params()) { |
1340 | let ty = self.make_ty(type_ref); | 1456 | let ty = self.make_ty(type_ref); |
1341 | let ty = self.insert_type_vars(ty); | ||
1342 | 1457 | ||
1343 | self.infer_pat(*pat, &ty); | 1458 | self.infer_pat(*pat, &ty); |
1344 | } | 1459 | } |
1345 | self.return_ty = { | 1460 | self.return_ty = { |
1346 | let ty = self.make_ty(signature.ret_type()); | 1461 | let ty = self.make_ty(signature.ret_type()); |
1347 | let ty = self.insert_type_vars(ty); | ||
1348 | ty | 1462 | ty |
1349 | }; | 1463 | }; |
1350 | } | 1464 | } |