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.rs84
1 files changed, 15 insertions, 69 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 7898740be..97e7c5f8c 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -14,7 +14,7 @@
14//! the `ena` crate, which is extracted from rustc. 14//! the `ena` crate, which is extracted from rustc.
15 15
16use std::borrow::Cow; 16use std::borrow::Cow;
17use std::mem; 17
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
@@ -27,8 +27,8 @@ use hir_def::{
27 path::{path, Path}, 27 path::{path, Path},
28 resolver::{HasResolver, Resolver, TypeNs}, 28 resolver::{HasResolver, Resolver, TypeNs},
29 type_ref::TypeRef, 29 type_ref::TypeRef,
30 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId, 30 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule, Lookup,
31 TypeAliasId, VariantId, 31 TraitId, TypeAliasId, VariantId,
32}; 32};
33use hir_expand::{diagnostics::DiagnosticSink, name::name}; 33use hir_expand::{diagnostics::DiagnosticSink, name::name};
34use la_arena::ArenaMap; 34use la_arena::ArenaMap;
@@ -36,13 +36,11 @@ use rustc_hash::FxHashMap;
36use stdx::impl_from; 36use stdx::impl_from;
37use syntax::SmolStr; 37use syntax::SmolStr;
38 38
39use super::{ 39use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty};
40 DomainGoal, Guidance, InEnvironment, ProjectionTy, Solution, TraitEnvironment, TraitRef, Ty,
41};
42use crate::{ 40use crate::{
43 db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic, 41 db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic,
44 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Canonical, Interner, 42 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyExt,
45 TyBuilder, TyExt, TyKind, 43 TyKind,
46}; 44};
47 45
48// This lint has a false positive here. See the link below for details. 46// This lint has a false positive here. See the link below for details.
@@ -227,8 +225,6 @@ struct InferenceContext<'a> {
227 resolver: Resolver, 225 resolver: Resolver,
228 table: unify::InferenceTable<'a>, 226 table: unify::InferenceTable<'a>,
229 trait_env: Arc<TraitEnvironment>, 227 trait_env: Arc<TraitEnvironment>,
230 obligations: Vec<DomainGoal>,
231 last_obligations_check: Option<u32>,
232 result: InferenceResult, 228 result: InferenceResult,
233 /// The return type of the function being inferred, or the closure if we're 229 /// The return type of the function being inferred, or the closure if we're
234 /// currently within one. 230 /// currently within one.
@@ -260,15 +256,15 @@ fn find_breakable<'c>(
260 256
261impl<'a> InferenceContext<'a> { 257impl<'a> InferenceContext<'a> {
262 fn new(db: &'a dyn HirDatabase, owner: DefWithBodyId, resolver: Resolver) -> Self { 258 fn new(db: &'a dyn HirDatabase, owner: DefWithBodyId, resolver: Resolver) -> Self {
263 let trait_env = 259 let krate = owner.module(db.upcast()).krate();
264 owner.as_generic_def_id().map_or_else(Default::default, |d| db.trait_environment(d)); 260 let trait_env = owner
261 .as_generic_def_id()
262 .map_or_else(|| Arc::new(TraitEnvironment::empty(krate)), |d| db.trait_environment(d));
265 InferenceContext { 263 InferenceContext {
266 result: InferenceResult::default(), 264 result: InferenceResult::default(),
267 table: unify::InferenceTable::new(db, trait_env.clone()), 265 table: unify::InferenceTable::new(db, trait_env.clone()),
268 obligations: Vec::default(),
269 last_obligations_check: None,
270 return_ty: TyKind::Error.intern(&Interner), // set in collect_fn_signature
271 trait_env, 266 trait_env,
267 return_ty: TyKind::Error.intern(&Interner), // set in collect_fn_signature
272 db, 268 db,
273 owner, 269 owner,
274 body: db.body(owner), 270 body: db.body(owner),
@@ -284,6 +280,7 @@ impl<'a> InferenceContext<'a> {
284 280
285 fn resolve_all(mut self) -> InferenceResult { 281 fn resolve_all(mut self) -> InferenceResult {
286 // FIXME resolve obligations as well (use Guidance if necessary) 282 // FIXME resolve obligations as well (use Guidance if necessary)
283 self.table.resolve_obligations_as_possible();
287 284
288 // make sure diverging type variables are marked as such 285 // make sure diverging type variables are marked as such
289 self.table.propagate_diverging_flag(); 286 self.table.propagate_diverging_flag();
@@ -357,44 +354,11 @@ impl<'a> InferenceContext<'a> {
357 } 354 }
358 355
359 fn resolve_obligations_as_possible(&mut self) { 356 fn resolve_obligations_as_possible(&mut self) {
360 let _span = profile::span("resolve_obligations_as_possible"); 357 self.table.resolve_obligations_as_possible();
361
362 let obligations = mem::replace(&mut self.obligations, Vec::new());
363 for obligation in obligations {
364 let in_env = InEnvironment::new(&self.trait_env.env, obligation.clone());
365 let canonicalized = self.canonicalize(in_env);
366 let solution =
367 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
368
369 match solution {
370 Some(Solution::Unique(canonical_subst)) => {
371 canonicalized.apply_solution(
372 self,
373 Canonical {
374 binders: canonical_subst.binders,
375 // FIXME: handle constraints
376 value: canonical_subst.value.subst,
377 },
378 );
379 }
380 Some(Solution::Ambig(Guidance::Definite(substs))) => {
381 canonicalized.apply_solution(self, substs);
382 self.obligations.push(obligation);
383 }
384 Some(_) => {
385 // FIXME use this when trying to resolve everything at the end
386 self.obligations.push(obligation);
387 }
388 None => {
389 // FIXME obligation cannot be fulfilled => diagnostic
390 }
391 };
392 }
393 } 358 }
394 359
395 fn push_obligation(&mut self, o: DomainGoal) { 360 fn push_obligation(&mut self, o: DomainGoal) {
396 self.obligations.push(o); 361 self.table.register_obligation(o.cast(&Interner));
397 self.last_obligations_check = None;
398 } 362 }
399 363
400 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 364 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
@@ -467,25 +431,7 @@ impl<'a> InferenceContext<'a> {
467 /// call). `make_ty` handles this already, but e.g. for field types we need 431 /// call). `make_ty` handles this already, but e.g. for field types we need
468 /// to do it as well. 432 /// to do it as well.
469 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 433 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
470 let ty = self.resolve_ty_as_possible(ty); 434 self.table.normalize_associated_types_in(ty)
471 fold_tys(
472 ty,
473 |ty, _| match ty.kind(&Interner) {
474 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
475 self.normalize_projection_ty(proj_ty.clone())
476 }
477 _ => ty,
478 },
479 DebruijnIndex::INNERMOST,
480 )
481 }
482
483 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
484 let var = self.table.new_type_var();
485 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
486 let obligation = alias_eq.cast(&Interner);
487 self.push_obligation(obligation);
488 var
489 } 435 }
490 436
491 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { 437 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) {