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.rs198
1 files changed, 98 insertions, 100 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index e4407ff50..bf2da2d4a 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -18,7 +18,7 @@ use std::mem;
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
21use chalk_ir::{cast::Cast, Mutability}; 21use chalk_ir::{cast::Cast, DebruijnIndex, Mutability};
22use hir_def::{ 22use hir_def::{
23 body::Body, 23 body::Body,
24 data::{ConstData, FunctionData, StaticData}, 24 data::{ConstData, FunctionData, StaticData},
@@ -37,12 +37,12 @@ use stdx::impl_from;
37use syntax::SmolStr; 37use syntax::SmolStr;
38 38
39use super::{ 39use super::{
40 traits::{DomainGoal, Guidance, Solution}, 40 DomainGoal, Guidance, InEnvironment, ProjectionTy, Solution, TraitEnvironment, TraitRef, Ty,
41 InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 41};
43use crate::{ 42use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 43 db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic,
45 to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind, 44 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Canonical, Interner,
45 TyBuilder, TyExt, TyKind,
46}; 46};
47 47
48// This lint has a false positive here. See the link below for details. 48// This lint has a false positive here. See the link below for details.
@@ -120,7 +120,7 @@ struct InternedStandardTypes {
120 120
121impl Default for InternedStandardTypes { 121impl Default for InternedStandardTypes {
122 fn default() -> Self { 122 fn default() -> Self {
123 InternedStandardTypes { unknown: TyKind::Unknown.intern(&Interner) } 123 InternedStandardTypes { unknown: TyKind::Error.intern(&Interner) }
124 } 124 }
125} 125}
126 126
@@ -131,10 +131,7 @@ pub struct InferenceResult {
131 method_resolutions: FxHashMap<ExprId, FunctionId>, 131 method_resolutions: FxHashMap<ExprId, FunctionId>,
132 /// For each field access expr, records the field it resolves to. 132 /// For each field access expr, records the field it resolves to.
133 field_resolutions: FxHashMap<ExprId, FieldId>, 133 field_resolutions: FxHashMap<ExprId, FieldId>,
134 /// For each field in record literal, records the field it resolves to. 134 /// For each struct literal or pattern, records the variant it resolves to.
135 record_field_resolutions: FxHashMap<ExprId, FieldId>,
136 record_pat_field_resolutions: FxHashMap<PatId, FieldId>,
137 /// For each struct literal, records the variant it resolves to.
138 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, 135 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
139 /// For each associated item record what it resolves to 136 /// For each associated item record what it resolves to
140 assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>, 137 assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>,
@@ -153,12 +150,6 @@ impl InferenceResult {
153 pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> { 150 pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> {
154 self.field_resolutions.get(&expr).copied() 151 self.field_resolutions.get(&expr).copied()
155 } 152 }
156 pub fn record_field_resolution(&self, expr: ExprId) -> Option<FieldId> {
157 self.record_field_resolutions.get(&expr).copied()
158 }
159 pub fn record_pat_field_resolution(&self, pat: PatId) -> Option<FieldId> {
160 self.record_pat_field_resolutions.get(&pat).copied()
161 }
162 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> { 153 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
163 self.variant_resolutions.get(&id.into()).copied() 154 self.variant_resolutions.get(&id.into()).copied()
164 } 155 }
@@ -210,6 +201,7 @@ struct InferenceContext<'a> {
210 table: unify::InferenceTable, 201 table: unify::InferenceTable,
211 trait_env: Arc<TraitEnvironment>, 202 trait_env: Arc<TraitEnvironment>,
212 obligations: Vec<DomainGoal>, 203 obligations: Vec<DomainGoal>,
204 last_obligations_check: Option<u32>,
213 result: InferenceResult, 205 result: InferenceResult,
214 /// The return type of the function being inferred, or the closure if we're 206 /// The return type of the function being inferred, or the closure if we're
215 /// currently within one. 207 /// currently within one.
@@ -245,7 +237,8 @@ impl<'a> InferenceContext<'a> {
245 result: InferenceResult::default(), 237 result: InferenceResult::default(),
246 table: unify::InferenceTable::new(), 238 table: unify::InferenceTable::new(),
247 obligations: Vec::default(), 239 obligations: Vec::default(),
248 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature 240 last_obligations_check: None,
241 return_ty: TyKind::Error.intern(&Interner), // set in collect_fn_signature
249 trait_env: owner 242 trait_env: owner
250 .as_generic_def_id() 243 .as_generic_def_id()
251 .map_or_else(Default::default, |d| db.trait_environment(d)), 244 .map_or_else(Default::default, |d| db.trait_environment(d)),
@@ -259,7 +252,7 @@ impl<'a> InferenceContext<'a> {
259 } 252 }
260 253
261 fn err_ty(&self) -> Ty { 254 fn err_ty(&self) -> Ty {
262 TyKind::Unknown.intern(&Interner) 255 TyKind::Error.intern(&Interner)
263 } 256 }
264 257
265 fn resolve_all(mut self) -> InferenceResult { 258 fn resolve_all(mut self) -> InferenceResult {
@@ -323,30 +316,44 @@ impl<'a> InferenceContext<'a> {
323 316
324 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 317 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
325 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 318 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
326 match ty.interned(&Interner) { 319 match ty.kind(&Interner) {
327 TyKind::Unknown => self.table.new_type_var(), 320 TyKind::Error => self.table.new_type_var(),
328 _ => ty, 321 _ => ty,
329 } 322 }
330 } 323 }
331 324
332 fn insert_type_vars(&mut self, ty: Ty) -> Ty { 325 fn insert_type_vars(&mut self, ty: Ty) -> Ty {
333 ty.fold(&mut |ty| self.insert_type_vars_shallow(ty)) 326 fold_tys(ty, |ty, _| self.insert_type_vars_shallow(ty), DebruijnIndex::INNERMOST)
334 } 327 }
335 328
336 fn resolve_obligations_as_possible(&mut self) { 329 fn resolve_obligations_as_possible(&mut self) {
330 if self.last_obligations_check == Some(self.table.revision) {
331 // no change
332 return;
333 }
334 let _span = profile::span("resolve_obligations_as_possible");
335
336 self.last_obligations_check = Some(self.table.revision);
337 let obligations = mem::replace(&mut self.obligations, Vec::new()); 337 let obligations = mem::replace(&mut self.obligations, Vec::new());
338 for obligation in obligations { 338 for obligation in obligations {
339 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone()); 339 let in_env = InEnvironment::new(&self.trait_env.env, obligation.clone());
340 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); 340 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
341 let solution = 341 let solution =
342 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); 342 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
343 343
344 match solution { 344 match solution {
345 Some(Solution::Unique(substs)) => { 345 Some(Solution::Unique(canonical_subst)) => {
346 canonicalized.apply_solution(self, substs.0); 346 canonicalized.apply_solution(
347 self,
348 Canonical {
349 binders: canonical_subst.binders,
350 // FIXME: handle constraints
351 value: canonical_subst.value.subst,
352 },
353 );
347 } 354 }
348 Some(Solution::Ambig(Guidance::Definite(substs))) => { 355 Some(Solution::Ambig(Guidance::Definite(substs))) => {
349 canonicalized.apply_solution(self, substs.0); 356 canonicalized.apply_solution(self, substs);
350 self.obligations.push(obligation); 357 self.obligations.push(obligation);
351 } 358 }
352 Some(_) => { 359 Some(_) => {
@@ -360,6 +367,11 @@ impl<'a> InferenceContext<'a> {
360 } 367 }
361 } 368 }
362 369
370 fn push_obligation(&mut self, o: DomainGoal) {
371 self.obligations.push(o);
372 self.last_obligations_check = None;
373 }
374
363 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 375 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
364 self.table.unify(ty1, ty2) 376 self.table.unify(ty1, ty2)
365 } 377 }
@@ -395,21 +407,19 @@ impl<'a> InferenceContext<'a> {
395 _ => panic!("resolve_associated_type called with non-associated type"), 407 _ => panic!("resolve_associated_type called with non-associated type"),
396 }; 408 };
397 let ty = self.table.new_type_var(); 409 let ty = self.table.new_type_var();
398 let substs = Substitution::build_for_def(self.db, res_assoc_ty) 410 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
399 .push(inner_ty) 411 .push(inner_ty)
400 .fill(params.iter().cloned()) 412 .fill(params.iter().cloned())
401 .build(); 413 .build();
402 let trait_ref =
403 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
404 let alias_eq = AliasEq { 414 let alias_eq = AliasEq {
405 alias: AliasTy::Projection(ProjectionTy { 415 alias: AliasTy::Projection(ProjectionTy {
406 associated_ty_id: to_assoc_type_id(res_assoc_ty), 416 associated_ty_id: to_assoc_type_id(res_assoc_ty),
407 substitution: substs, 417 substitution: trait_ref.substitution.clone(),
408 }), 418 }),
409 ty: ty.clone(), 419 ty: ty.clone(),
410 }; 420 };
411 self.obligations.push(trait_ref.cast(&Interner)); 421 self.push_obligation(trait_ref.cast(&Interner));
412 self.obligations.push(alias_eq.cast(&Interner)); 422 self.push_obligation(alias_eq.cast(&Interner));
413 self.resolve_ty_as_possible(ty) 423 self.resolve_ty_as_possible(ty)
414 } 424 }
415 None => self.err_ty(), 425 None => self.err_ty(),
@@ -424,19 +434,23 @@ impl<'a> InferenceContext<'a> {
424 /// to do it as well. 434 /// to do it as well.
425 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 435 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
426 let ty = self.resolve_ty_as_possible(ty); 436 let ty = self.resolve_ty_as_possible(ty);
427 ty.fold(&mut |ty| match ty.interned(&Interner) { 437 fold_tys(
428 TyKind::Alias(AliasTy::Projection(proj_ty)) => { 438 ty,
429 self.normalize_projection_ty(proj_ty.clone()) 439 |ty, _| match ty.kind(&Interner) {
430 } 440 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
431 _ => ty, 441 self.normalize_projection_ty(proj_ty.clone())
432 }) 442 }
443 _ => ty,
444 },
445 DebruijnIndex::INNERMOST,
446 )
433 } 447 }
434 448
435 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty { 449 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
436 let var = self.table.new_type_var(); 450 let var = self.table.new_type_var();
437 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() }; 451 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
438 let obligation = alias_eq.cast(&Interner); 452 let obligation = alias_eq.cast(&Interner);
439 self.obligations.push(obligation); 453 self.push_obligation(obligation);
440 var 454 var
441 } 455 }
442 456
@@ -458,56 +472,32 @@ impl<'a> InferenceContext<'a> {
458 TypeNs::AdtId(AdtId::StructId(strukt)) => { 472 TypeNs::AdtId(AdtId::StructId(strukt)) => {
459 let substs = ctx.substs_from_path(path, strukt.into(), true); 473 let substs = ctx.substs_from_path(path, strukt.into(), true);
460 let ty = self.db.ty(strukt.into()); 474 let ty = self.db.ty(strukt.into());
461 let ty = self.insert_type_vars(ty.subst(&substs)); 475 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
462 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) 476 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
463 } 477 }
464 TypeNs::AdtId(AdtId::UnionId(u)) => { 478 TypeNs::AdtId(AdtId::UnionId(u)) => {
465 let substs = ctx.substs_from_path(path, u.into(), true); 479 let substs = ctx.substs_from_path(path, u.into(), true);
466 let ty = self.db.ty(u.into()); 480 let ty = self.db.ty(u.into());
467 let ty = self.insert_type_vars(ty.subst(&substs)); 481 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
468 forbid_unresolved_segments((ty, Some(u.into())), unresolved) 482 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
469 } 483 }
470 TypeNs::EnumVariantId(var) => { 484 TypeNs::EnumVariantId(var) => {
471 let substs = ctx.substs_from_path(path, var.into(), true); 485 let substs = ctx.substs_from_path(path, var.into(), true);
472 let ty = self.db.ty(var.parent.into()); 486 let ty = self.db.ty(var.parent.into());
473 let ty = self.insert_type_vars(ty.subst(&substs)); 487 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
474 forbid_unresolved_segments((ty, Some(var.into())), unresolved) 488 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
475 } 489 }
476 TypeNs::SelfType(impl_id) => { 490 TypeNs::SelfType(impl_id) => {
477 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 491 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
478 let substs = Substitution::type_params_for_generics(self.db, &generics); 492 let substs = generics.type_params_subst(self.db);
479 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 493 let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
480 match unresolved { 494 self.resolve_variant_on_alias(ty, unresolved, path)
481 None => {
482 let variant = ty_variant(&ty);
483 (ty, variant)
484 }
485 Some(1) => {
486 let segment = path.mod_path().segments().last().unwrap();
487 // this could be an enum variant or associated type
488 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
489 let enum_data = self.db.enum_data(enum_id);
490 if let Some(local_id) = enum_data.variant(segment) {
491 let variant = EnumVariantId { parent: enum_id, local_id };
492 return (ty, Some(variant.into()));
493 }
494 }
495 // FIXME potentially resolve assoc type
496 (self.err_ty(), None)
497 }
498 Some(_) => {
499 // FIXME diagnostic
500 (self.err_ty(), None)
501 }
502 }
503 } 495 }
504 TypeNs::TypeAliasId(it) => { 496 TypeNs::TypeAliasId(it) => {
505 let substs = Substitution::build_for_def(self.db, it) 497 let ty = TyBuilder::def_ty(self.db, it.into())
506 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 498 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
507 .build(); 499 .build();
508 let ty = self.db.ty(it.into()).subst(&substs); 500 self.resolve_variant_on_alias(ty, unresolved, path)
509 let variant = ty_variant(&ty);
510 forbid_unresolved_segments((ty, variant), unresolved)
511 } 501 }
512 TypeNs::AdtSelfType(_) => { 502 TypeNs::AdtSelfType(_) => {
513 // FIXME this could happen in array size expressions, once we're checking them 503 // FIXME this could happen in array size expressions, once we're checking them
@@ -531,19 +521,46 @@ impl<'a> InferenceContext<'a> {
531 result 521 result
532 } else { 522 } else {
533 // FIXME diagnostic 523 // FIXME diagnostic
534 (TyKind::Unknown.intern(&Interner), None) 524 (TyKind::Error.intern(&Interner), None)
535 } 525 }
536 } 526 }
527 }
537 528
538 fn ty_variant(ty: &Ty) -> Option<VariantId> { 529 fn resolve_variant_on_alias(
539 ty.as_adt().and_then(|(adt_id, _)| match adt_id { 530 &mut self,
540 AdtId::StructId(s) => Some(VariantId::StructId(s)), 531 ty: Ty,
541 AdtId::UnionId(u) => Some(VariantId::UnionId(u)), 532 unresolved: Option<usize>,
542 AdtId::EnumId(_) => { 533 path: &Path,
543 // FIXME Error E0071, expected struct, variant or union type, found enum `Foo` 534 ) -> (Ty, Option<VariantId>) {
544 None 535 match unresolved {
536 None => {
537 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
538 AdtId::StructId(s) => Some(VariantId::StructId(s)),
539 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
540 AdtId::EnumId(_) => {
541 // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
542 None
543 }
544 });
545 (ty, variant)
546 }
547 Some(1) => {
548 let segment = path.mod_path().segments().last().unwrap();
549 // this could be an enum variant or associated type
550 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
551 let enum_data = self.db.enum_data(enum_id);
552 if let Some(local_id) = enum_data.variant(segment) {
553 let variant = EnumVariantId { parent: enum_id, local_id };
554 return (ty, Some(variant.into()));
555 }
545 } 556 }
546 }) 557 // FIXME potentially resolve assoc type
558 (self.err_ty(), None)
559 }
560 Some(_) => {
561 // FIXME diagnostic
562 (self.err_ty(), None)
563 }
547 } 564 }
548 } 565 }
549 566
@@ -681,25 +698,6 @@ impl<'a> InferenceContext<'a> {
681 } 698 }
682} 699}
683 700
684/// The kinds of placeholders we need during type inference. There's separate
685/// values for general types, and for integer and float variables. The latter
686/// two are used for inference of literal values (e.g. `100` could be one of
687/// several integer types).
688#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
689pub struct InferenceVar {
690 index: u32,
691}
692
693impl InferenceVar {
694 fn to_inner(self) -> unify::TypeVarId {
695 unify::TypeVarId(self.index)
696 }
697
698 fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self {
699 InferenceVar { index }
700 }
701}
702
703/// When inferring an expression, we propagate downward whatever type hint we 701/// When inferring an expression, we propagate downward whatever type hint we
704/// are able in the form of an `Expectation`. 702/// are able in the form of an `Expectation`.
705#[derive(Clone, PartialEq, Eq, Debug)] 703#[derive(Clone, PartialEq, Eq, Debug)]
@@ -744,7 +742,7 @@ impl Expectation {
744 fn none() -> Self { 742 fn none() -> Self {
745 Expectation { 743 Expectation {
746 // FIXME 744 // FIXME
747 ty: TyKind::Unknown.intern(&Interner), 745 ty: TyKind::Error.intern(&Interner),
748 rvalue_hint: false, 746 rvalue_hint: false,
749 } 747 }
750 } 748 }
@@ -752,7 +750,7 @@ impl Expectation {
752 fn coercion_target(&self) -> Ty { 750 fn coercion_target(&self) -> Ty {
753 if self.rvalue_hint { 751 if self.rvalue_hint {
754 // FIXME 752 // FIXME
755 TyKind::Unknown.intern(&Interner) 753 TyKind::Error.intern(&Interner)
756 } else { 754 } else {
757 self.ty.clone() 755 self.ty.clone()
758 } 756 }