diff options
Diffstat (limited to 'crates/hir_ty/src/infer.rs')
-rw-r--r-- | crates/hir_ty/src/infer.rs | 70 |
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..8cf59821f 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 | }; |
43 | use crate::{ | 43 | use 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 | ||
47 | pub(crate) use unify::unify; | 48 | pub(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: to_assoc_type_id(res_assoc_ty), | ||
389 | parameters: 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 | } |