aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-19 18:03:36 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-19 18:03:36 +0000
commit1c296d54e3dcc36c1a778873f26035000a352ba2 (patch)
tree0a6ce660ee32080287284c93bffaaaada91f3584 /crates/ra_hir/src/ty.rs
parentbade91db081a3465dea3547ab8ab669f78fde9dc (diff)
parent5f3509e140d19b989db418a00ac6778c622cde5d (diff)
Merge #576
576: Beginnings of generics r=matklad a=flodiebold This implements the beginnings of the generics infrastructure; generic parameters for structs work and are correctly substituted in fields. Functions and methods aren't handled at all yet (as the tests show). The name resolution in `ty` really needs refactoring now, I hope to do that next ;) Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs370
1 files changed, 308 insertions, 62 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 8d6493887..9b7182485 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -37,6 +37,8 @@ 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::GenericParams,
41 path::GenericArg,
40}; 42};
41 43
42/// The ID of a type variable. 44/// The ID of a type variable.
@@ -151,10 +153,20 @@ impl Expectation {
151 } 153 }
152} 154}
153 155
156/// A list of substitutions for generic parameters.
157#[derive(Clone, PartialEq, Eq, Debug)]
158pub struct Substs(Arc<[Ty]>);
159
160impl Substs {
161 pub fn empty() -> Substs {
162 Substs(Arc::new([]))
163 }
164}
165
154/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs). 166/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs).
155/// 167///
156/// This should be cheap to clone. 168/// This should be cheap to clone.
157#[derive(Clone, PartialEq, Eq, Hash, Debug)] 169#[derive(Clone, PartialEq, Eq, Debug)]
158pub enum Ty { 170pub enum Ty {
159 /// The primitive boolean type. Written as `bool`. 171 /// The primitive boolean type. Written as `bool`.
160 Bool, 172 Bool,
@@ -175,7 +187,8 @@ pub enum Ty {
175 def_id: DefId, 187 def_id: DefId,
176 /// The name, for displaying. 188 /// The name, for displaying.
177 name: Name, 189 name: Name,
178 // later we'll need generic substitutions here 190 /// Substitutions for the generic parameters of the type.
191 substs: Substs,
179 }, 192 },
180 193
181 /// The pointee of a string slice. Written as `str`. 194 /// The pointee of a string slice. Written as `str`.
@@ -234,9 +247,15 @@ pub enum Ty {
234 247
235 // Opaque (`impl Trait`) type found in a return type. 248 // Opaque (`impl Trait`) type found in a return type.
236 // Opaque(DefId, Substs), 249 // Opaque(DefId, Substs),
250 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
251 Param {
252 /// The index of the parameter (starting with parameters from the
253 /// surrounding impl, then the current function).
254 idx: u32,
255 /// The name of the parameter, for displaying.
256 name: Name,
257 },
237 258
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 259 /// A type variable used during type checking. Not to be confused with a
241 /// type parameter. 260 /// type parameter.
242 Infer(InferTy), 261 Infer(InferTy),
@@ -250,7 +269,7 @@ pub enum Ty {
250} 269}
251 270
252/// A function signature. 271/// A function signature.
253#[derive(Clone, PartialEq, Eq, Hash, Debug)] 272#[derive(Clone, PartialEq, Eq, Debug)]
254pub struct FnSig { 273pub struct FnSig {
255 input: Vec<Ty>, 274 input: Vec<Ty>,
256 output: Ty, 275 output: Ty,
@@ -259,8 +278,12 @@ pub struct FnSig {
259impl Ty { 278impl Ty {
260 pub(crate) fn from_hir( 279 pub(crate) fn from_hir(
261 db: &impl HirDatabase, 280 db: &impl HirDatabase,
281 // TODO: the next three parameters basically describe the scope for name
282 // resolution; this should be refactored into something like a general
283 // resolver architecture
262 module: &Module, 284 module: &Module,
263 impl_block: Option<&ImplBlock>, 285 impl_block: Option<&ImplBlock>,
286 generics: &GenericParams,
264 type_ref: &TypeRef, 287 type_ref: &TypeRef,
265 ) -> Self { 288 ) -> Self {
266 match type_ref { 289 match type_ref {
@@ -268,32 +291,32 @@ impl Ty {
268 TypeRef::Tuple(inner) => { 291 TypeRef::Tuple(inner) => {
269 let inner_tys = inner 292 let inner_tys = inner
270 .iter() 293 .iter()
271 .map(|tr| Ty::from_hir(db, module, impl_block, tr)) 294 .map(|tr| Ty::from_hir(db, module, impl_block, generics, tr))
272 .collect::<Vec<_>>(); 295 .collect::<Vec<_>>();
273 Ty::Tuple(inner_tys.into()) 296 Ty::Tuple(inner_tys.into())
274 } 297 }
275 TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, path), 298 TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, generics, path),
276 TypeRef::RawPtr(inner, mutability) => { 299 TypeRef::RawPtr(inner, mutability) => {
277 let inner_ty = Ty::from_hir(db, module, impl_block, inner); 300 let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner);
278 Ty::RawPtr(Arc::new(inner_ty), *mutability) 301 Ty::RawPtr(Arc::new(inner_ty), *mutability)
279 } 302 }
280 TypeRef::Array(inner) => { 303 TypeRef::Array(inner) => {
281 let inner_ty = Ty::from_hir(db, module, impl_block, inner); 304 let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner);
282 Ty::Array(Arc::new(inner_ty)) 305 Ty::Array(Arc::new(inner_ty))
283 } 306 }
284 TypeRef::Slice(inner) => { 307 TypeRef::Slice(inner) => {
285 let inner_ty = Ty::from_hir(db, module, impl_block, inner); 308 let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner);
286 Ty::Slice(Arc::new(inner_ty)) 309 Ty::Slice(Arc::new(inner_ty))
287 } 310 }
288 TypeRef::Reference(inner, mutability) => { 311 TypeRef::Reference(inner, mutability) => {
289 let inner_ty = Ty::from_hir(db, module, impl_block, inner); 312 let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner);
290 Ty::Ref(Arc::new(inner_ty), *mutability) 313 Ty::Ref(Arc::new(inner_ty), *mutability)
291 } 314 }
292 TypeRef::Placeholder => Ty::Unknown, 315 TypeRef::Placeholder => Ty::Unknown,
293 TypeRef::Fn(params) => { 316 TypeRef::Fn(params) => {
294 let mut inner_tys = params 317 let mut inner_tys = params
295 .iter() 318 .iter()
296 .map(|tr| Ty::from_hir(db, module, impl_block, tr)) 319 .map(|tr| Ty::from_hir(db, module, impl_block, generics, tr))
297 .collect::<Vec<_>>(); 320 .collect::<Vec<_>>();
298 let return_ty = inner_tys 321 let return_ty = inner_tys
299 .pop() 322 .pop()
@@ -312,15 +335,19 @@ impl Ty {
312 db: &impl HirDatabase, 335 db: &impl HirDatabase,
313 module: &Module, 336 module: &Module,
314 impl_block: Option<&ImplBlock>, 337 impl_block: Option<&ImplBlock>,
338 generics: &GenericParams,
315 type_ref: Option<&TypeRef>, 339 type_ref: Option<&TypeRef>,
316 ) -> Self { 340 ) -> Self {
317 type_ref.map_or(Ty::Unknown, |t| Ty::from_hir(db, module, impl_block, t)) 341 type_ref.map_or(Ty::Unknown, |t| {
342 Ty::from_hir(db, module, impl_block, generics, t)
343 })
318 } 344 }
319 345
320 pub(crate) fn from_hir_path( 346 pub(crate) fn from_hir_path(
321 db: &impl HirDatabase, 347 db: &impl HirDatabase,
322 module: &Module, 348 module: &Module,
323 impl_block: Option<&ImplBlock>, 349 impl_block: Option<&ImplBlock>,
350 generics: &GenericParams,
324 path: &Path, 351 path: &Path,
325 ) -> Self { 352 ) -> Self {
326 if let Some(name) = path.as_ident() { 353 if let Some(name) = path.as_ident() {
@@ -329,7 +356,15 @@ impl Ty {
329 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { 356 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) {
330 return Ty::Float(float_ty); 357 return Ty::Float(float_ty);
331 } else if name.as_known_name() == Some(KnownName::SelfType) { 358 } 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())); 359 // TODO pass the impl block's generics?
360 let generics = &GenericParams::default();
361 return Ty::from_hir_opt(
362 db,
363 module,
364 None,
365 generics,
366 impl_block.map(|i| i.target_type()),
367 );
333 } else if let Some(known) = name.as_known_name() { 368 } else if let Some(known) = name.as_known_name() {
334 match known { 369 match known {
335 KnownName::Bool => return Ty::Bool, 370 KnownName::Bool => return Ty::Bool,
@@ -337,16 +372,89 @@ impl Ty {
337 KnownName::Str => return Ty::Str, 372 KnownName::Str => return Ty::Str,
338 _ => {} 373 _ => {}
339 } 374 }
375 } else if let Some(generic_param) = generics.find_by_name(&name) {
376 return Ty::Param {
377 idx: generic_param.idx,
378 name: generic_param.name.clone(),
379 };
340 } 380 }
341 } 381 }
342 382
343 // Resolve in module (in type namespace) 383 // Resolve in module (in type namespace)
344 let resolved = if let Some(r) = module.resolve_path(db, path).take_types() { 384 let resolved = match module.resolve_path(db, path).take_types() {
345 r 385 Some(r) => r,
346 } else { 386 None => return Ty::Unknown,
347 return Ty::Unknown;
348 }; 387 };
349 db.type_for_def(resolved) 388 let ty = db.type_for_def(resolved);
389 let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved);
390 ty.apply_substs(substs)
391 }
392
393 /// Collect generic arguments from a path into a `Substs`. See also
394 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
395 fn substs_from_path(
396 db: &impl HirDatabase,
397 // the scope of the segment...
398 module: &Module,
399 impl_block: Option<&ImplBlock>,
400 outer_generics: &GenericParams,
401 path: &Path,
402 resolved: DefId,
403 ) -> Substs {
404 let mut substs = Vec::new();
405 let def = resolved.resolve(db);
406 let last = path
407 .segments
408 .last()
409 .expect("path should have at least one segment");
410 let (def_generics, segment) = match def {
411 Def::Struct(s) => (s.generic_params(db), last),
412 Def::Enum(e) => (e.generic_params(db), last),
413 Def::Function(f) => (f.generic_params(db), last),
414 Def::Trait(t) => (t.generic_params(db), last),
415 Def::EnumVariant(ev) => {
416 // the generic args for an enum variant may be either specified
417 // on the segment referring to the enum, or on the segment
418 // referring to the variant. So `Option::<T>::None` and
419 // `Option::None::<T>` are both allowed (though the former is
420 // preferred). See also `def_ids_for_path_segments` in rustc.
421 let len = path.segments.len();
422 let segment = if len >= 2 && path.segments[len - 2].args_and_bindings.is_some() {
423 // Option::<T>::None
424 &path.segments[len - 2]
425 } else {
426 // Option::None::<T>
427 last
428 };
429 (ev.parent_enum(db).generic_params(db), segment)
430 }
431 _ => return Substs::empty(),
432 };
433 // substs_from_path
434 if let Some(generic_args) = &segment.args_and_bindings {
435 // if args are provided, it should be all of them, but we can't rely on that
436 let param_count = def_generics.params.len();
437 for arg in generic_args.args.iter().take(param_count) {
438 match arg {
439 GenericArg::Type(type_ref) => {
440 let ty = Ty::from_hir(db, module, impl_block, outer_generics, type_ref);
441 substs.push(ty);
442 }
443 }
444 }
445 }
446 // add placeholders for args that were not provided
447 // TODO: handle defaults
448 for _ in segment
449 .args_and_bindings
450 .as_ref()
451 .map(|ga| ga.args.len())
452 .unwrap_or(0)..def_generics.params.len()
453 {
454 substs.push(Ty::Unknown);
455 }
456 assert_eq!(substs.len(), def_generics.params.len());
457 Substs(substs.into())
350 } 458 }
351 459
352 pub fn unit() -> Self { 460 pub fn unit() -> Self {
@@ -374,7 +482,14 @@ impl Ty {
374 } 482 }
375 sig_mut.output.walk_mut(f); 483 sig_mut.output.walk_mut(f);
376 } 484 }
377 Ty::Adt { .. } => {} // need to walk type parameters later 485 Ty::Adt { substs, .. } => {
486 // Without an Arc::make_mut_slice, we can't avoid the clone here:
487 let mut v: Vec<_> = substs.0.iter().cloned().collect();
488 for t in &mut v {
489 t.walk_mut(f);
490 }
491 substs.0 = v.into();
492 }
378 _ => {} 493 _ => {}
379 } 494 }
380 } 495 }
@@ -394,6 +509,49 @@ impl Ty {
394 _ => None, 509 _ => None,
395 } 510 }
396 } 511 }
512
513 /// If this is a type with type parameters (an ADT or function), replaces
514 /// the `Substs` for these type parameters with the given ones. (So e.g. if
515 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
516 /// `Option<u32>` afterwards.)
517 pub fn apply_substs(self, substs: Substs) -> Ty {
518 match self {
519 Ty::Adt { def_id, name, .. } => Ty::Adt {
520 def_id,
521 name,
522 substs,
523 },
524 _ => self,
525 }
526 }
527
528 /// Replaces type parameters in this type using the given `Substs`. (So e.g.
529 /// if `self` is `&[T]`, where type parameter T has index 0, and the
530 /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.)
531 pub fn subst(self, substs: &Substs) -> Ty {
532 self.fold(&mut |ty| match ty {
533 Ty::Param { idx, name } => {
534 if (idx as usize) < substs.0.len() {
535 substs.0[idx as usize].clone()
536 } else {
537 // TODO: does this indicate a bug? i.e. should we always
538 // have substs for all type params? (they might contain the
539 // params themselves again...)
540 Ty::Param { idx, name }
541 }
542 }
543 ty => ty,
544 })
545 }
546
547 /// Returns the type parameters of this type if it has some (i.e. is an ADT
548 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
549 fn substs(&self) -> Option<Substs> {
550 match self {
551 Ty::Adt { substs, .. } => Some(substs.clone()),
552 _ => None,
553 }
554 }
397} 555}
398 556
399impl fmt::Display for Ty { 557impl fmt::Display for Ty {
@@ -425,7 +583,17 @@ impl fmt::Display for Ty {
425 .to_fmt(f)?; 583 .to_fmt(f)?;
426 write!(f, " -> {}", sig.output) 584 write!(f, " -> {}", sig.output)
427 } 585 }
428 Ty::Adt { name, .. } => write!(f, "{}", name), 586 Ty::Adt { name, substs, .. } => {
587 write!(f, "{}", name)?;
588 if substs.0.len() > 0 {
589 join(substs.0.iter())
590 .surround_with("<", ">")
591 .separator(", ")
592 .to_fmt(f)?;
593 }
594 Ok(())
595 }
596 Ty::Param { name, .. } => write!(f, "{}", name),
429 Ty::Unknown => write!(f, "[unknown]"), 597 Ty::Unknown => write!(f, "[unknown]"),
430 Ty::Infer(..) => write!(f, "_"), 598 Ty::Infer(..) => write!(f, "_"),
431 } 599 }
@@ -440,28 +608,49 @@ fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty {
440 let signature = f.signature(db); 608 let signature = f.signature(db);
441 let module = f.module(db); 609 let module = f.module(db);
442 let impl_block = f.impl_block(db); 610 let impl_block = f.impl_block(db);
443 // TODO we ignore type parameters for now 611 let generics = f.generic_params(db);
444 let input = signature 612 let input = signature
445 .params() 613 .params()
446 .iter() 614 .iter()
447 .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr)) 615 .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), &generics, tr))
448 .collect::<Vec<_>>(); 616 .collect::<Vec<_>>();
449 let output = Ty::from_hir(db, &module, impl_block.as_ref(), signature.ret_type()); 617 let output = Ty::from_hir(
618 db,
619 &module,
620 impl_block.as_ref(),
621 &generics,
622 signature.ret_type(),
623 );
450 let sig = FnSig { input, output }; 624 let sig = FnSig { input, output };
451 Ty::FnPtr(Arc::new(sig)) 625 Ty::FnPtr(Arc::new(sig))
452} 626}
453 627
628fn make_substs(generics: &GenericParams) -> Substs {
629 Substs(
630 generics
631 .params
632 .iter()
633 .map(|_p| Ty::Unknown)
634 .collect::<Vec<_>>()
635 .into(),
636 )
637}
638
454fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { 639fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
640 let generics = s.generic_params(db);
455 Ty::Adt { 641 Ty::Adt {
456 def_id: s.def_id(), 642 def_id: s.def_id(),
457 name: s.name(db).unwrap_or_else(Name::missing), 643 name: s.name(db).unwrap_or_else(Name::missing),
644 substs: make_substs(&generics),
458 } 645 }
459} 646}
460 647
461pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { 648pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
649 let generics = s.generic_params(db);
462 Ty::Adt { 650 Ty::Adt {
463 def_id: s.def_id(), 651 def_id: s.def_id(),
464 name: s.name(db).unwrap_or_else(Name::missing), 652 name: s.name(db).unwrap_or_else(Name::missing),
653 substs: make_substs(&generics),
465 } 654 }
466} 655}
467 656
@@ -495,9 +684,9 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty {
495 684
496pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Option<Ty> { 685pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Option<Ty> {
497 let def = def_id.resolve(db); 686 let def = def_id.resolve(db);
498 let variant_data = match def { 687 let (variant_data, generics) = match def {
499 Def::Struct(s) => s.variant_data(db), 688 Def::Struct(s) => (s.variant_data(db), s.generic_params(db)),
500 Def::EnumVariant(ev) => ev.variant_data(db), 689 Def::EnumVariant(ev) => (ev.variant_data(db), ev.parent_enum(db).generic_params(db)),
501 // TODO: unions 690 // TODO: unions
502 _ => panic!( 691 _ => panic!(
503 "trying to get type for field in non-struct/variant {:?}", 692 "trying to get type for field in non-struct/variant {:?}",
@@ -507,7 +696,13 @@ pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name)
507 let module = def_id.module(db); 696 let module = def_id.module(db);
508 let impl_block = def_id.impl_block(db); 697 let impl_block = def_id.impl_block(db);
509 let type_ref = variant_data.get_field_type_ref(&field)?; 698 let type_ref = variant_data.get_field_type_ref(&field)?;
510 Some(Ty::from_hir(db, &module, impl_block.as_ref(), &type_ref)) 699 Some(Ty::from_hir(
700 db,
701 &module,
702 impl_block.as_ref(),
703 &generics,
704 &type_ref,
705 ))
511} 706}
512 707
513/// The result of type inference: A mapping from expressions and patterns to types. 708/// The result of type inference: A mapping from expressions and patterns to types.
@@ -684,8 +879,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
684 self.type_of_pat.insert(pat, ty); 879 self.type_of_pat.insert(pat, ty);
685 } 880 }
686 881
687 fn make_ty(&self, type_ref: &TypeRef) -> Ty { 882 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
688 Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref) 883 // TODO provide generics of function
884 let generics = GenericParams::default();
885 let ty = Ty::from_hir(
886 self.db,
887 &self.module,
888 self.impl_block.as_ref(),
889 &generics,
890 type_ref,
891 );
892 let ty = self.insert_type_vars(ty);
893 ty
894 }
895
896 fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs) -> bool {
897 substs1
898 .0
899 .iter()
900 .zip(substs2.0.iter())
901 .all(|(t1, t2)| self.unify(t1, t2))
689 } 902 }
690 903
691 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 904 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
@@ -708,12 +921,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
708 (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2, 921 (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2,
709 ( 922 (
710 Ty::Adt { 923 Ty::Adt {
711 def_id: def_id1, .. 924 def_id: def_id1,
925 substs: substs1,
926 ..
712 }, 927 },
713 Ty::Adt { 928 Ty::Adt {
714 def_id: def_id2, .. 929 def_id: def_id2,
930 substs: substs2,
931 ..
715 }, 932 },
716 ) if def_id1 == def_id2 => true, 933 ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2),
717 (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2), 934 (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2),
718 (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2), 935 (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2),
719 (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2), 936 (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2),
@@ -848,73 +1065,100 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
848 Some(ty) 1065 Some(ty)
849 } 1066 }
850 1067
851 fn resolve_variant(&self, path: Option<&Path>) -> (Ty, Option<DefId>) { 1068 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<DefId>) {
852 let path = if let Some(path) = path { 1069 let path = match path {
853 path 1070 Some(path) => path,
854 } else { 1071 None => return (Ty::Unknown, None),
855 return (Ty::Unknown, None);
856 }; 1072 };
857 let def_id = if let Some(def_id) = self.module.resolve_path(self.db, &path).take_types() { 1073 let def_id = match self.module.resolve_path(self.db, &path).take_types() {
858 def_id 1074 Some(def_id) => def_id,
859 } else { 1075 _ => return (Ty::Unknown, None),
860 return (Ty::Unknown, None);
861 }; 1076 };
1077 // TODO remove the duplication between here and `Ty::from_path`?
1078 // TODO provide generics of function
1079 let generics = GenericParams::default();
1080 let substs = Ty::substs_from_path(
1081 self.db,
1082 &self.module,
1083 self.impl_block.as_ref(),
1084 &generics,
1085 path,
1086 def_id,
1087 );
862 match def_id.resolve(self.db) { 1088 match def_id.resolve(self.db) {
863 Def::Struct(s) => { 1089 Def::Struct(s) => {
864 let ty = type_for_struct(self.db, s); 1090 let ty = type_for_struct(self.db, s);
1091 let ty = self.insert_type_vars(ty.apply_substs(substs));
865 (ty, Some(def_id)) 1092 (ty, Some(def_id))
866 } 1093 }
867 Def::EnumVariant(ev) => { 1094 Def::EnumVariant(ev) => {
868 let ty = type_for_enum_variant(self.db, ev); 1095 let ty = type_for_enum_variant(self.db, ev);
1096 let ty = self.insert_type_vars(ty.apply_substs(substs));
869 (ty, Some(def_id)) 1097 (ty, Some(def_id))
870 } 1098 }
871 _ => (Ty::Unknown, None), 1099 _ => (Ty::Unknown, None),
872 } 1100 }
873 } 1101 }
874 1102
875 fn resolve_fields(&self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> { 1103 fn resolve_fields(&mut self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> {
876 let def_id = self.module.resolve_path(self.db, path?).take_types()?; 1104 let (ty, def_id) = self.resolve_variant(path);
1105 let def_id = def_id?;
877 let def = def_id.resolve(self.db); 1106 let def = def_id.resolve(self.db);
878 1107
879 match def { 1108 match def {
880 Def::Struct(s) => { 1109 Def::Struct(s) => {
881 let fields = s.fields(self.db); 1110 let fields = s.fields(self.db);
882 Some((type_for_struct(self.db, s), fields)) 1111 Some((ty, fields))
883 } 1112 }
884 Def::EnumVariant(ev) => { 1113 Def::EnumVariant(ev) => {
885 let fields = ev.fields(self.db); 1114 let fields = ev.fields(self.db);
886 Some((type_for_enum_variant(self.db, ev), fields)) 1115 Some((ty, fields))
887 } 1116 }
888 _ => None, 1117 _ => None,
889 } 1118 }
890 } 1119 }
891 1120
892 fn infer_tuple_struct_pat(&mut self, path: Option<&Path>, subpats: &[PatId]) -> Ty { 1121 fn infer_tuple_struct_pat(
1122 &mut self,
1123 path: Option<&Path>,
1124 subpats: &[PatId],
1125 expected: &Ty,
1126 ) -> Ty {
893 let (ty, fields) = self 1127 let (ty, fields) = self
894 .resolve_fields(path) 1128 .resolve_fields(path)
895 .unwrap_or((Ty::Unknown, Vec::new())); 1129 .unwrap_or((Ty::Unknown, Vec::new()));
896 1130
1131 self.unify(&ty, expected);
1132
1133 let substs = ty.substs().expect("adt should have substs");
1134
897 for (i, &subpat) in subpats.iter().enumerate() { 1135 for (i, &subpat) in subpats.iter().enumerate() {
898 let expected_ty = fields 1136 let expected_ty = fields
899 .get(i) 1137 .get(i)
900 .and_then(|field| field.ty(self.db)) 1138 .and_then(|field| field.ty(self.db))
901 .unwrap_or(Ty::Unknown); 1139 .unwrap_or(Ty::Unknown)
1140 .subst(&substs);
902 self.infer_pat(subpat, &expected_ty); 1141 self.infer_pat(subpat, &expected_ty);
903 } 1142 }
904 1143
905 ty 1144 ty
906 } 1145 }
907 1146
908 fn infer_struct_pat(&mut self, path: Option<&Path>, subpats: &[FieldPat]) -> Ty { 1147 fn infer_struct_pat(&mut self, path: Option<&Path>, subpats: &[FieldPat], expected: &Ty) -> Ty {
909 let (ty, fields) = self 1148 let (ty, fields) = self
910 .resolve_fields(path) 1149 .resolve_fields(path)
911 .unwrap_or((Ty::Unknown, Vec::new())); 1150 .unwrap_or((Ty::Unknown, Vec::new()));
912 1151
1152 self.unify(&ty, expected);
1153
1154 let substs = ty.substs().expect("adt should have substs");
1155
913 for subpat in subpats { 1156 for subpat in subpats {
914 let matching_field = fields.iter().find(|field| field.name() == &subpat.name); 1157 let matching_field = fields.iter().find(|field| field.name() == &subpat.name);
915 let expected_ty = matching_field 1158 let expected_ty = matching_field
916 .and_then(|field| field.ty(self.db)) 1159 .and_then(|field| field.ty(self.db))
917 .unwrap_or(Ty::Unknown); 1160 .unwrap_or(Ty::Unknown)
1161 .subst(&substs);
918 self.infer_pat(subpat.pat, &expected_ty); 1162 self.infer_pat(subpat.pat, &expected_ty);
919 } 1163 }
920 1164
@@ -959,11 +1203,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
959 Pat::TupleStruct { 1203 Pat::TupleStruct {
960 path: ref p, 1204 path: ref p,
961 args: ref subpats, 1205 args: ref subpats,
962 } => self.infer_tuple_struct_pat(p.as_ref(), subpats), 1206 } => self.infer_tuple_struct_pat(p.as_ref(), subpats, expected),
963 Pat::Struct { 1207 Pat::Struct {
964 path: ref p, 1208 path: ref p,
965 args: ref fields, 1209 args: ref fields,
966 } => self.infer_struct_pat(p.as_ref(), fields), 1210 } => self.infer_struct_pat(p.as_ref(), fields, expected),
967 Pat::Path(path) => self 1211 Pat::Path(path) => self
968 .module 1212 .module
969 .resolve_path(self.db, &path) 1213 .resolve_path(self.db, &path)
@@ -1155,11 +1399,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1155 spread, 1399 spread,
1156 } => { 1400 } => {
1157 let (ty, def_id) = self.resolve_variant(path.as_ref()); 1401 let (ty, def_id) = self.resolve_variant(path.as_ref());
1402 let substs = ty.substs().expect("adt should have substs");
1158 for field in fields { 1403 for field in fields {
1159 let field_ty = if let Some(def_id) = def_id { 1404 let field_ty = if let Some(def_id) = def_id {
1160 self.db 1405 self.db
1161 .type_for_field(def_id, field.name.clone()) 1406 .type_for_field(def_id, field.name.clone())
1162 .unwrap_or(Ty::Unknown) 1407 .unwrap_or(Ty::Unknown)
1408 .subst(&substs)
1163 } else { 1409 } else {
1164 Ty::Unknown 1410 Ty::Unknown
1165 }; 1411 };
@@ -1180,7 +1426,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1180 let i = name.to_string().parse::<usize>().ok(); 1426 let i = name.to_string().parse::<usize>().ok();
1181 i.and_then(|i| fields.get(i).cloned()) 1427 i.and_then(|i| fields.get(i).cloned())
1182 } 1428 }
1183 Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, name.clone()), 1429 Ty::Adt {
1430 def_id, ref substs, ..
1431 } => self
1432 .db
1433 .type_for_field(def_id, name.clone())
1434 .map(|ty| ty.subst(substs)),
1184 _ => None, 1435 _ => None,
1185 }) 1436 })
1186 .unwrap_or(Ty::Unknown); 1437 .unwrap_or(Ty::Unknown);
@@ -1193,7 +1444,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1193 Expr::Cast { expr, type_ref } => { 1444 Expr::Cast { expr, type_ref } => {
1194 let _inner_ty = self.infer_expr(*expr, &Expectation::none()); 1445 let _inner_ty = self.infer_expr(*expr, &Expectation::none());
1195 let cast_ty = self.make_ty(type_ref); 1446 let cast_ty = self.make_ty(type_ref);
1196 let cast_ty = self.insert_type_vars(cast_ty);
1197 // TODO check the cast... 1447 // TODO check the cast...
1198 cast_ty 1448 cast_ty
1199 } 1449 }
@@ -1305,12 +1555,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1305 type_ref, 1555 type_ref,
1306 initializer, 1556 initializer,
1307 } => { 1557 } => {
1308 let decl_ty = Ty::from_hir_opt( 1558 let decl_ty = type_ref
1309 self.db, 1559 .as_ref()
1310 &self.module, 1560 .map(|tr| self.make_ty(tr))
1311 self.impl_block.as_ref(), 1561 .unwrap_or(Ty::Unknown);
1312 type_ref.as_ref(),
1313 );
1314 let decl_ty = self.insert_type_vars(decl_ty); 1562 let decl_ty = self.insert_type_vars(decl_ty);
1315 let ty = if let Some(expr) = initializer { 1563 let ty = if let Some(expr) = initializer {
1316 let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); 1564 let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty));
@@ -1338,13 +1586,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1338 let body = Arc::clone(&self.body); // avoid borrow checker problem 1586 let body = Arc::clone(&self.body); // avoid borrow checker problem
1339 for (type_ref, pat) in signature.params().iter().zip(body.params()) { 1587 for (type_ref, pat) in signature.params().iter().zip(body.params()) {
1340 let ty = self.make_ty(type_ref); 1588 let ty = self.make_ty(type_ref);
1341 let ty = self.insert_type_vars(ty);
1342 1589
1343 self.infer_pat(*pat, &ty); 1590 self.infer_pat(*pat, &ty);
1344 } 1591 }
1345 self.return_ty = { 1592 self.return_ty = {
1346 let ty = self.make_ty(signature.ret_type()); 1593 let ty = self.make_ty(signature.ret_type());
1347 let ty = self.insert_type_vars(ty);
1348 ty 1594 ty
1349 }; 1595 };
1350 } 1596 }