aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer.rs')
-rw-r--r--crates/hir_ty/src/infer.rs70
1 files changed, 41 insertions, 29 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 4d771a91e..fbfedb4e6 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -41,7 +41,8 @@ use super::{
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, 41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
45 to_assoc_type_id, AliasTy, Interner, TyKind,
45}; 46};
46 47
47pub(crate) use unify::unify; 48pub(crate) use unify::unify;
@@ -169,7 +170,7 @@ impl Index<ExprId> for InferenceResult {
169 type Output = Ty; 170 type Output = Ty;
170 171
171 fn index(&self, expr: ExprId) -> &Ty { 172 fn index(&self, expr: ExprId) -> &Ty {
172 self.type_of_expr.get(expr).unwrap_or(&Ty::Unknown) 173 self.type_of_expr.get(expr).unwrap_or(&Ty(TyKind::Unknown))
173 } 174 }
174} 175}
175 176
@@ -177,7 +178,7 @@ impl Index<PatId> for InferenceResult {
177 type Output = Ty; 178 type Output = Ty;
178 179
179 fn index(&self, pat: PatId) -> &Ty { 180 fn index(&self, pat: PatId) -> &Ty {
180 self.type_of_pat.get(pat).unwrap_or(&Ty::Unknown) 181 self.type_of_pat.get(pat).unwrap_or(&Ty(TyKind::Unknown))
181 } 182 }
182} 183}
183 184
@@ -226,8 +227,10 @@ impl<'a> InferenceContext<'a> {
226 result: InferenceResult::default(), 227 result: InferenceResult::default(),
227 table: unify::InferenceTable::new(), 228 table: unify::InferenceTable::new(),
228 obligations: Vec::default(), 229 obligations: Vec::default(),
229 return_ty: Ty::Unknown, // set in collect_fn_signature 230 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature
230 trait_env: TraitEnvironment::lower(db, &resolver), 231 trait_env: owner
232 .as_generic_def_id()
233 .map_or_else(Default::default, |d| db.trait_environment(d)),
231 db, 234 db,
232 owner, 235 owner,
233 body: db.body(owner), 236 body: db.body(owner),
@@ -237,15 +240,19 @@ impl<'a> InferenceContext<'a> {
237 } 240 }
238 } 241 }
239 242
243 fn err_ty(&self) -> Ty {
244 TyKind::Unknown.intern(&Interner)
245 }
246
240 fn resolve_all(mut self) -> InferenceResult { 247 fn resolve_all(mut self) -> InferenceResult {
241 // FIXME resolve obligations as well (use Guidance if necessary) 248 // FIXME resolve obligations as well (use Guidance if necessary)
242 let mut result = std::mem::take(&mut self.result); 249 let mut result = std::mem::take(&mut self.result);
243 for ty in result.type_of_expr.values_mut() { 250 for ty in result.type_of_expr.values_mut() {
244 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); 251 let resolved = self.table.resolve_ty_completely(ty.clone());
245 *ty = resolved; 252 *ty = resolved;
246 } 253 }
247 for ty in result.type_of_pat.values_mut() { 254 for ty in result.type_of_pat.values_mut() {
248 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); 255 let resolved = self.table.resolve_ty_completely(ty.clone());
249 *ty = resolved; 256 *ty = resolved;
250 } 257 }
251 result 258 result
@@ -287,7 +294,7 @@ impl<'a> InferenceContext<'a> {
287 // FIXME use right resolver for block 294 // FIXME use right resolver for block
288 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) 295 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
289 .with_impl_trait_mode(impl_trait_mode); 296 .with_impl_trait_mode(impl_trait_mode);
290 let ty = Ty::from_hir(&ctx, type_ref); 297 let ty = ctx.lower_ty(type_ref);
291 let ty = self.insert_type_vars(ty); 298 let ty = self.insert_type_vars(ty);
292 self.normalize_associated_types_in(ty) 299 self.normalize_associated_types_in(ty)
293 } 300 }
@@ -298,8 +305,8 @@ impl<'a> InferenceContext<'a> {
298 305
299 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 306 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
300 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 307 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
301 match ty { 308 match ty.interned(&Interner) {
302 Ty::Unknown => self.table.new_type_var(), 309 TyKind::Unknown => self.table.new_type_var(),
303 _ => ty, 310 _ => ty,
304 } 311 }
305 } 312 }
@@ -377,13 +384,16 @@ impl<'a> InferenceContext<'a> {
377 let trait_ref = TraitRef { trait_, substs: substs.clone() }; 384 let trait_ref = TraitRef { trait_, substs: substs.clone() };
378 let projection = ProjectionPredicate { 385 let projection = ProjectionPredicate {
379 ty: ty.clone(), 386 ty: ty.clone(),
380 projection_ty: ProjectionTy { associated_ty: res_assoc_ty, parameters: substs }, 387 projection_ty: ProjectionTy {
388 associated_ty_id: to_assoc_type_id(res_assoc_ty),
389 substitution: substs,
390 },
381 }; 391 };
382 self.obligations.push(Obligation::Trait(trait_ref)); 392 self.obligations.push(Obligation::Trait(trait_ref));
383 self.obligations.push(Obligation::Projection(projection)); 393 self.obligations.push(Obligation::Projection(projection));
384 self.resolve_ty_as_possible(ty) 394 self.resolve_ty_as_possible(ty)
385 } 395 }
386 None => Ty::Unknown, 396 None => self.err_ty(),
387 } 397 }
388 } 398 }
389 399
@@ -395,8 +405,10 @@ impl<'a> InferenceContext<'a> {
395 /// to do it as well. 405 /// to do it as well.
396 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 406 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
397 let ty = self.resolve_ty_as_possible(ty); 407 let ty = self.resolve_ty_as_possible(ty);
398 ty.fold(&mut |ty| match ty { 408 ty.fold(&mut |ty| match ty.interned(&Interner) {
399 Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty), 409 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
410 self.normalize_projection_ty(proj_ty.clone())
411 }
400 _ => ty, 412 _ => ty,
401 }) 413 })
402 } 414 }
@@ -412,7 +424,7 @@ impl<'a> InferenceContext<'a> {
412 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { 424 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) {
413 let path = match path { 425 let path = match path {
414 Some(path) => path, 426 Some(path) => path,
415 None => return (Ty::Unknown, None), 427 None => return (self.err_ty(), None),
416 }; 428 };
417 let resolver = &self.resolver; 429 let resolver = &self.resolver;
418 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 430 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
@@ -421,30 +433,30 @@ impl<'a> InferenceContext<'a> {
421 let (resolution, unresolved) = 433 let (resolution, unresolved) =
422 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { 434 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
423 Some(it) => it, 435 Some(it) => it,
424 None => return (Ty::Unknown, None), 436 None => return (self.err_ty(), None),
425 }; 437 };
426 return match resolution { 438 return match resolution {
427 TypeNs::AdtId(AdtId::StructId(strukt)) => { 439 TypeNs::AdtId(AdtId::StructId(strukt)) => {
428 let substs = Ty::substs_from_path(&ctx, path, strukt.into(), true); 440 let substs = ctx.substs_from_path(path, strukt.into(), true);
429 let ty = self.db.ty(strukt.into()); 441 let ty = self.db.ty(strukt.into());
430 let ty = self.insert_type_vars(ty.subst(&substs)); 442 let ty = self.insert_type_vars(ty.subst(&substs));
431 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) 443 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
432 } 444 }
433 TypeNs::AdtId(AdtId::UnionId(u)) => { 445 TypeNs::AdtId(AdtId::UnionId(u)) => {
434 let substs = Ty::substs_from_path(&ctx, path, u.into(), true); 446 let substs = ctx.substs_from_path(path, u.into(), true);
435 let ty = self.db.ty(u.into()); 447 let ty = self.db.ty(u.into());
436 let ty = self.insert_type_vars(ty.subst(&substs)); 448 let ty = self.insert_type_vars(ty.subst(&substs));
437 forbid_unresolved_segments((ty, Some(u.into())), unresolved) 449 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
438 } 450 }
439 TypeNs::EnumVariantId(var) => { 451 TypeNs::EnumVariantId(var) => {
440 let substs = Ty::substs_from_path(&ctx, path, var.into(), true); 452 let substs = ctx.substs_from_path(path, var.into(), true);
441 let ty = self.db.ty(var.parent.into()); 453 let ty = self.db.ty(var.parent.into());
442 let ty = self.insert_type_vars(ty.subst(&substs)); 454 let ty = self.insert_type_vars(ty.subst(&substs));
443 forbid_unresolved_segments((ty, Some(var.into())), unresolved) 455 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
444 } 456 }
445 TypeNs::SelfType(impl_id) => { 457 TypeNs::SelfType(impl_id) => {
446 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 458 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
447 let substs = Substs::type_params_for_generics(&generics); 459 let substs = Substs::type_params_for_generics(self.db, &generics);
448 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 460 let ty = self.db.impl_self_ty(impl_id).subst(&substs);
449 match unresolved { 461 match unresolved {
450 None => { 462 None => {
@@ -462,11 +474,11 @@ impl<'a> InferenceContext<'a> {
462 } 474 }
463 } 475 }
464 // FIXME potentially resolve assoc type 476 // FIXME potentially resolve assoc type
465 (Ty::Unknown, None) 477 (self.err_ty(), None)
466 } 478 }
467 Some(_) => { 479 Some(_) => {
468 // FIXME diagnostic 480 // FIXME diagnostic
469 (Ty::Unknown, None) 481 (self.err_ty(), None)
470 } 482 }
471 } 483 }
472 } 484 }
@@ -480,15 +492,15 @@ impl<'a> InferenceContext<'a> {
480 } 492 }
481 TypeNs::AdtSelfType(_) => { 493 TypeNs::AdtSelfType(_) => {
482 // FIXME this could happen in array size expressions, once we're checking them 494 // FIXME this could happen in array size expressions, once we're checking them
483 (Ty::Unknown, None) 495 (self.err_ty(), None)
484 } 496 }
485 TypeNs::GenericParam(_) => { 497 TypeNs::GenericParam(_) => {
486 // FIXME potentially resolve assoc type 498 // FIXME potentially resolve assoc type
487 (Ty::Unknown, None) 499 (self.err_ty(), None)
488 } 500 }
489 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { 501 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => {
490 // FIXME diagnostic 502 // FIXME diagnostic
491 (Ty::Unknown, None) 503 (self.err_ty(), None)
492 } 504 }
493 }; 505 };
494 506
@@ -500,7 +512,7 @@ impl<'a> InferenceContext<'a> {
500 result 512 result
501 } else { 513 } else {
502 // FIXME diagnostic 514 // FIXME diagnostic
503 (Ty::Unknown, None) 515 (TyKind::Unknown.intern(&Interner), None)
504 } 516 }
505 } 517 }
506 518
@@ -529,7 +541,7 @@ impl<'a> InferenceContext<'a> {
529 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) 541 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
530 .with_impl_trait_mode(ImplTraitLoweringMode::Param); 542 .with_impl_trait_mode(ImplTraitLoweringMode::Param);
531 let param_tys = 543 let param_tys =
532 data.params.iter().map(|type_ref| Ty::from_hir(&ctx, type_ref)).collect::<Vec<_>>(); 544 data.params.iter().map(|type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
533 for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) { 545 for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) {
534 let ty = self.insert_type_vars(ty); 546 let ty = self.insert_type_vars(ty);
535 let ty = self.normalize_associated_types_in(ty); 547 let ty = self.normalize_associated_types_in(ty);
@@ -711,12 +723,12 @@ impl Expectation {
711 723
712 /// This expresses no expectation on the type. 724 /// This expresses no expectation on the type.
713 fn none() -> Self { 725 fn none() -> Self {
714 Expectation { ty: Ty::Unknown, rvalue_hint: false } 726 Expectation { ty: TyKind::Unknown.intern(&Interner), rvalue_hint: false }
715 } 727 }
716 728
717 fn coercion_target(&self) -> &Ty { 729 fn coercion_target(&self) -> &Ty {
718 if self.rvalue_hint { 730 if self.rvalue_hint {
719 &Ty::Unknown 731 &Ty(TyKind::Unknown)
720 } else { 732 } else {
721 &self.ty 733 &self.ty
722 } 734 }