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.rs192
1 files changed, 83 insertions, 109 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 0ee851a74..f1cebbdb9 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -13,8 +13,6 @@
13//! to certain types. To record this, we use the union-find implementation from 13//! to certain types. To record this, we use the union-find implementation from
14//! the `ena` crate, which is extracted from rustc. 14//! the `ena` crate, which is extracted from rustc.
15 15
16use std::borrow::Cow;
17use std::mem;
18use std::ops::Index; 16use std::ops::Index;
19use std::sync::Arc; 17use std::sync::Arc;
20 18
@@ -27,8 +25,8 @@ use hir_def::{
27 path::{path, Path}, 25 path::{path, Path},
28 resolver::{HasResolver, Resolver, TypeNs}, 26 resolver::{HasResolver, Resolver, TypeNs},
29 type_ref::TypeRef, 27 type_ref::TypeRef,
30 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId, 28 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule, Lookup,
31 TypeAliasId, VariantId, 29 TraitId, TypeAliasId, VariantId,
32}; 30};
33use hir_expand::{diagnostics::DiagnosticSink, name::name}; 31use hir_expand::{diagnostics::DiagnosticSink, name::name};
34use la_arena::ArenaMap; 32use la_arena::ArenaMap;
@@ -36,13 +34,11 @@ use rustc_hash::FxHashMap;
36use stdx::impl_from; 34use stdx::impl_from;
37use syntax::SmolStr; 35use syntax::SmolStr;
38 36
39use super::{ 37use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty};
40 DomainGoal, Guidance, InEnvironment, ProjectionTy, Solution, TraitEnvironment, TraitRef, Ty,
41};
42use crate::{ 38use crate::{
43 db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic, 39 db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic,
44 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Canonical, Interner, 40 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Goal, Interner, TyBuilder,
45 TyBuilder, TyExt, TyKind, 41 TyExt, TyKind,
46}; 42};
47 43
48// This lint has a false positive here. See the link below for details. 44// This lint has a false positive here. See the link below for details.
@@ -106,6 +102,14 @@ impl Default for BindingMode {
106 } 102 }
107} 103}
108 104
105#[derive(Debug)]
106pub(crate) struct InferOk {
107 goals: Vec<InEnvironment<Goal>>,
108}
109#[derive(Debug)]
110pub(crate) struct TypeError;
111pub(crate) type InferResult = Result<InferOk, TypeError>;
112
109/// A mismatch between an expected and an inferred type. 113/// A mismatch between an expected and an inferred type.
110#[derive(Clone, PartialEq, Eq, Debug, Hash)] 114#[derive(Clone, PartialEq, Eq, Debug, Hash)]
111pub struct TypeMismatch { 115pub struct TypeMismatch {
@@ -217,10 +221,8 @@ struct InferenceContext<'a> {
217 owner: DefWithBodyId, 221 owner: DefWithBodyId,
218 body: Arc<Body>, 222 body: Arc<Body>,
219 resolver: Resolver, 223 resolver: Resolver,
220 table: unify::InferenceTable, 224 table: unify::InferenceTable<'a>,
221 trait_env: Arc<TraitEnvironment>, 225 trait_env: Arc<TraitEnvironment>,
222 obligations: Vec<DomainGoal>,
223 last_obligations_check: Option<u32>,
224 result: InferenceResult, 226 result: InferenceResult,
225 /// The return type of the function being inferred, or the closure if we're 227 /// The return type of the function being inferred, or the closure if we're
226 /// currently within one. 228 /// currently within one.
@@ -252,15 +254,15 @@ fn find_breakable<'c>(
252 254
253impl<'a> InferenceContext<'a> { 255impl<'a> InferenceContext<'a> {
254 fn new(db: &'a dyn HirDatabase, owner: DefWithBodyId, resolver: Resolver) -> Self { 256 fn new(db: &'a dyn HirDatabase, owner: DefWithBodyId, resolver: Resolver) -> Self {
257 let krate = owner.module(db.upcast()).krate();
258 let trait_env = owner
259 .as_generic_def_id()
260 .map_or_else(|| Arc::new(TraitEnvironment::empty(krate)), |d| db.trait_environment(d));
255 InferenceContext { 261 InferenceContext {
256 result: InferenceResult::default(), 262 result: InferenceResult::default(),
257 table: unify::InferenceTable::new(), 263 table: unify::InferenceTable::new(db, trait_env.clone()),
258 obligations: Vec::default(), 264 trait_env,
259 last_obligations_check: None,
260 return_ty: TyKind::Error.intern(&Interner), // set in collect_fn_signature 265 return_ty: TyKind::Error.intern(&Interner), // set in collect_fn_signature
261 trait_env: owner
262 .as_generic_def_id()
263 .map_or_else(Default::default, |d| db.trait_environment(d)),
264 db, 266 db,
265 owner, 267 owner,
266 body: db.body(owner), 268 body: db.body(owner),
@@ -271,19 +273,25 @@ impl<'a> InferenceContext<'a> {
271 } 273 }
272 274
273 fn err_ty(&self) -> Ty { 275 fn err_ty(&self) -> Ty {
274 TyKind::Error.intern(&Interner) 276 self.result.standard_types.unknown.clone()
275 } 277 }
276 278
277 fn resolve_all(mut self) -> InferenceResult { 279 fn resolve_all(mut self) -> InferenceResult {
278 // FIXME resolve obligations as well (use Guidance if necessary) 280 // FIXME resolve obligations as well (use Guidance if necessary)
281 self.table.resolve_obligations_as_possible();
282
283 // make sure diverging type variables are marked as such
284 self.table.propagate_diverging_flag();
279 let mut result = std::mem::take(&mut self.result); 285 let mut result = std::mem::take(&mut self.result);
280 for ty in result.type_of_expr.values_mut() { 286 for ty in result.type_of_expr.values_mut() {
281 let resolved = self.table.resolve_ty_completely(ty.clone()); 287 *ty = self.table.resolve_ty_completely(ty.clone());
282 *ty = resolved;
283 } 288 }
284 for ty in result.type_of_pat.values_mut() { 289 for ty in result.type_of_pat.values_mut() {
285 let resolved = self.table.resolve_ty_completely(ty.clone()); 290 *ty = self.table.resolve_ty_completely(ty.clone());
286 *ty = resolved; 291 }
292 for mismatch in result.type_mismatches.values_mut() {
293 mismatch.expected = self.table.resolve_ty_completely(mismatch.expected.clone());
294 mismatch.actual = self.table.resolve_ty_completely(mismatch.actual.clone());
287 } 295 }
288 result 296 result
289 } 297 }
@@ -337,6 +345,14 @@ impl<'a> InferenceContext<'a> {
337 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 345 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
338 match ty.kind(&Interner) { 346 match ty.kind(&Interner) {
339 TyKind::Error => self.table.new_type_var(), 347 TyKind::Error => self.table.new_type_var(),
348 TyKind::InferenceVar(..) => {
349 let ty_resolved = self.resolve_ty_shallow(&ty);
350 if ty_resolved.is_unknown() {
351 self.table.new_type_var()
352 } else {
353 ty
354 }
355 }
340 _ => ty, 356 _ => ty,
341 } 357 }
342 } 358 }
@@ -346,66 +362,19 @@ impl<'a> InferenceContext<'a> {
346 } 362 }
347 363
348 fn resolve_obligations_as_possible(&mut self) { 364 fn resolve_obligations_as_possible(&mut self) {
349 if self.last_obligations_check == Some(self.table.revision) { 365 self.table.resolve_obligations_as_possible();
350 // no change
351 return;
352 }
353 let _span = profile::span("resolve_obligations_as_possible");
354
355 self.last_obligations_check = Some(self.table.revision);
356 let obligations = mem::replace(&mut self.obligations, Vec::new());
357 for obligation in obligations {
358 let in_env = InEnvironment::new(&self.trait_env.env, obligation.clone());
359 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
360 let solution =
361 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
362
363 match solution {
364 Some(Solution::Unique(canonical_subst)) => {
365 canonicalized.apply_solution(
366 self,
367 Canonical {
368 binders: canonical_subst.binders,
369 // FIXME: handle constraints
370 value: canonical_subst.value.subst,
371 },
372 );
373 }
374 Some(Solution::Ambig(Guidance::Definite(substs))) => {
375 canonicalized.apply_solution(self, substs);
376 self.obligations.push(obligation);
377 }
378 Some(_) => {
379 // FIXME use this when trying to resolve everything at the end
380 self.obligations.push(obligation);
381 }
382 None => {
383 // FIXME obligation cannot be fulfilled => diagnostic
384 }
385 };
386 }
387 } 366 }
388 367
389 fn push_obligation(&mut self, o: DomainGoal) { 368 fn push_obligation(&mut self, o: DomainGoal) {
390 self.obligations.push(o); 369 self.table.register_obligation(o.cast(&Interner));
391 self.last_obligations_check = None;
392 } 370 }
393 371
394 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 372 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
395 self.table.unify(ty1, ty2) 373 self.table.unify(ty1, ty2)
396 } 374 }
397 375
398 /// Resolves the type as far as currently possible, replacing type variables 376 fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
399 /// by their known types. All types returned by the infer_* functions should
400 /// be resolved as far as possible, i.e. contain no type variables with
401 /// known type.
402 fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty {
403 self.resolve_obligations_as_possible(); 377 self.resolve_obligations_as_possible();
404
405 self.table.resolve_ty_as_possible(ty)
406 }
407
408 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> {
409 self.table.resolve_ty_shallow(ty) 378 self.table.resolve_ty_shallow(ty)
410 } 379 }
411 380
@@ -439,7 +408,7 @@ impl<'a> InferenceContext<'a> {
439 }; 408 };
440 self.push_obligation(trait_ref.cast(&Interner)); 409 self.push_obligation(trait_ref.cast(&Interner));
441 self.push_obligation(alias_eq.cast(&Interner)); 410 self.push_obligation(alias_eq.cast(&Interner));
442 self.resolve_ty_as_possible(ty) 411 ty
443 } 412 }
444 None => self.err_ty(), 413 None => self.err_ty(),
445 } 414 }
@@ -452,25 +421,7 @@ impl<'a> InferenceContext<'a> {
452 /// call). `make_ty` handles this already, but e.g. for field types we need 421 /// call). `make_ty` handles this already, but e.g. for field types we need
453 /// to do it as well. 422 /// to do it as well.
454 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 423 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
455 let ty = self.resolve_ty_as_possible(ty); 424 self.table.normalize_associated_types_in(ty)
456 fold_tys(
457 ty,
458 |ty, _| match ty.kind(&Interner) {
459 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
460 self.normalize_projection_ty(proj_ty.clone())
461 }
462 _ => ty,
463 },
464 DebruijnIndex::INNERMOST,
465 )
466 }
467
468 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
469 let var = self.table.new_type_var();
470 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
471 let obligation = alias_eq.cast(&Interner);
472 self.push_obligation(obligation);
473 var
474 } 425 }
475 426
476 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { 427 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) {
@@ -720,17 +671,23 @@ impl<'a> InferenceContext<'a> {
720/// When inferring an expression, we propagate downward whatever type hint we 671/// When inferring an expression, we propagate downward whatever type hint we
721/// are able in the form of an `Expectation`. 672/// are able in the form of an `Expectation`.
722#[derive(Clone, PartialEq, Eq, Debug)] 673#[derive(Clone, PartialEq, Eq, Debug)]
723struct Expectation { 674enum Expectation {
724 ty: Ty, 675 None,
725 /// See the `rvalue_hint` method. 676 HasType(Ty),
726 rvalue_hint: bool, 677 // Castable(Ty), // rustc has this, we currently just don't propagate an expectation for casts
678 RValueLikeUnsized(Ty),
727} 679}
728 680
729impl Expectation { 681impl Expectation {
730 /// The expectation that the type of the expression needs to equal the given 682 /// The expectation that the type of the expression needs to equal the given
731 /// type. 683 /// type.
732 fn has_type(ty: Ty) -> Self { 684 fn has_type(ty: Ty) -> Self {
733 Expectation { ty, rvalue_hint: false } 685 if ty.is_unknown() {
686 // FIXME: get rid of this?
687 Expectation::None
688 } else {
689 Expectation::HasType(ty)
690 }
734 } 691 }
735 692
736 /// The following explanation is copied straight from rustc: 693 /// The following explanation is copied straight from rustc:
@@ -754,24 +711,41 @@ impl Expectation {
754 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169 711 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
755 /// for examples of where this comes up,. 712 /// for examples of where this comes up,.
756 fn rvalue_hint(ty: Ty) -> Self { 713 fn rvalue_hint(ty: Ty) -> Self {
757 Expectation { ty, rvalue_hint: true } 714 match ty.strip_references().kind(&Interner) {
715 TyKind::Slice(_) | TyKind::Str | TyKind::Dyn(_) => Expectation::RValueLikeUnsized(ty),
716 _ => Expectation::has_type(ty),
717 }
758 } 718 }
759 719
760 /// This expresses no expectation on the type. 720 /// This expresses no expectation on the type.
761 fn none() -> Self { 721 fn none() -> Self {
762 Expectation { 722 Expectation::None
763 // FIXME 723 }
764 ty: TyKind::Error.intern(&Interner), 724
765 rvalue_hint: false, 725 fn resolve(&self, table: &mut unify::InferenceTable) -> Expectation {
726 match self {
727 Expectation::None => Expectation::None,
728 Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
729 Expectation::RValueLikeUnsized(t) => {
730 Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
731 }
766 } 732 }
767 } 733 }
768 734
769 fn coercion_target(&self) -> Ty { 735 fn to_option(&self, table: &mut unify::InferenceTable) -> Option<Ty> {
770 if self.rvalue_hint { 736 match self.resolve(table) {
771 // FIXME 737 Expectation::None => None,
772 TyKind::Error.intern(&Interner) 738 Expectation::HasType(t) |
773 } else { 739 // Expectation::Castable(t) |
774 self.ty.clone() 740 Expectation::RValueLikeUnsized(t) => Some(t),
741 }
742 }
743
744 fn only_has_type(&self, table: &mut unify::InferenceTable) -> Option<Ty> {
745 match self {
746 Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
747 // Expectation::Castable(_) |
748 Expectation::RValueLikeUnsized(_) | Expectation::None => None,
775 } 749 }
776 } 750 }
777} 751}