aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer.rs
diff options
context:
space:
mode:
authorSeivan Heidari <[email protected]>2019-12-23 14:35:31 +0000
committerSeivan Heidari <[email protected]>2019-12-23 14:35:31 +0000
commitb21d9337d9200e2cfdc90b386591c72c302dc03e (patch)
treef81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_ty/src/infer.rs
parent18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff)
parentce07a2daa9e53aa86a769f8641b14c2878444fbc (diff)
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir_ty/src/infer.rs')
-rw-r--r--crates/ra_hir_ty/src/infer.rs361
1 files changed, 133 insertions, 228 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index 1e9f4b208..e97b81473 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -18,19 +18,18 @@ use std::mem;
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
21use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
22use rustc_hash::FxHashMap; 21use rustc_hash::FxHashMap;
23 22
24use hir_def::{ 23use hir_def::{
25 body::Body, 24 body::Body,
26 data::{ConstData, FunctionData}, 25 data::{ConstData, FunctionData},
27 expr::{BindingAnnotation, ExprId, PatId}, 26 expr::{BindingAnnotation, ExprId, PatId},
28 path::{known, Path}, 27 path::{path, Path},
29 resolver::{HasResolver, Resolver, TypeNs}, 28 resolver::{HasResolver, Resolver, TypeNs},
30 type_ref::{Mutability, TypeRef}, 29 type_ref::{Mutability, TypeRef},
31 AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId, 30 AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId,
32}; 31};
33use hir_expand::{diagnostics::DiagnosticSink, name}; 32use hir_expand::{diagnostics::DiagnosticSink, name::name};
34use ra_arena::map::ArenaMap; 33use ra_arena::map::ArenaMap;
35use ra_prof::profile; 34use ra_prof::profile;
36use test_utils::tested_by; 35use test_utils::tested_by;
@@ -43,6 +42,8 @@ use super::{
43}; 42};
44use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; 43use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic};
45 44
45pub(crate) use unify::unify;
46
46macro_rules! ty_app { 47macro_rules! ty_app {
47 ($ctor:pat, $param:pat) => { 48 ($ctor:pat, $param:pat) => {
48 crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param }) 49 crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param })
@@ -191,11 +192,16 @@ struct InferenceContext<'a, D: HirDatabase> {
191 owner: DefWithBodyId, 192 owner: DefWithBodyId,
192 body: Arc<Body>, 193 body: Arc<Body>,
193 resolver: Resolver, 194 resolver: Resolver,
194 var_unification_table: InPlaceUnificationTable<TypeVarId>, 195 table: unify::InferenceTable,
195 trait_env: Arc<TraitEnvironment>, 196 trait_env: Arc<TraitEnvironment>,
196 obligations: Vec<Obligation>, 197 obligations: Vec<Obligation>,
197 result: InferenceResult, 198 result: InferenceResult,
198 /// The return type of the function being inferred. 199 /// The return type of the function being inferred, or the closure if we're
200 /// currently within one.
201 ///
202 /// We might consider using a nested inference context for checking
203 /// closures, but currently this is the only field that will change there,
204 /// so it doesn't make sense.
199 return_ty: Ty, 205 return_ty: Ty,
200 206
201 /// Impls of `CoerceUnsized` used in coercion. 207 /// Impls of `CoerceUnsized` used in coercion.
@@ -209,7 +215,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
209 fn new(db: &'a D, owner: DefWithBodyId, resolver: Resolver) -> Self { 215 fn new(db: &'a D, owner: DefWithBodyId, resolver: Resolver) -> Self {
210 InferenceContext { 216 InferenceContext {
211 result: InferenceResult::default(), 217 result: InferenceResult::default(),
212 var_unification_table: InPlaceUnificationTable::new(), 218 table: unify::InferenceTable::new(),
213 obligations: Vec::default(), 219 obligations: Vec::default(),
214 return_ty: Ty::Unknown, // set in collect_fn_signature 220 return_ty: Ty::Unknown, // set in collect_fn_signature
215 trait_env: TraitEnvironment::lower(db, &resolver), 221 trait_env: TraitEnvironment::lower(db, &resolver),
@@ -224,13 +230,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
224 fn resolve_all(mut self) -> InferenceResult { 230 fn resolve_all(mut self) -> InferenceResult {
225 // FIXME resolve obligations as well (use Guidance if necessary) 231 // FIXME resolve obligations as well (use Guidance if necessary)
226 let mut result = mem::replace(&mut self.result, InferenceResult::default()); 232 let mut result = mem::replace(&mut self.result, InferenceResult::default());
227 let mut tv_stack = Vec::new();
228 for ty in result.type_of_expr.values_mut() { 233 for ty in result.type_of_expr.values_mut() {
229 let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); 234 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown));
230 *ty = resolved; 235 *ty = resolved;
231 } 236 }
232 for ty in result.type_of_pat.values_mut() { 237 for ty in result.type_of_pat.values_mut() {
233 let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); 238 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown));
234 *ty = resolved; 239 *ty = resolved;
235 } 240 }
236 result 241 result
@@ -275,96 +280,38 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
275 self.normalize_associated_types_in(ty) 280 self.normalize_associated_types_in(ty)
276 } 281 }
277 282
278 fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool { 283 /// Replaces `impl Trait` in `ty` by type variables and obligations for
279 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 284 /// those variables. This is done for function arguments when calling a
280 } 285 /// function, and for return types when inside the function body, i.e. in
281 286 /// the cases where the `impl Trait` is 'transparent'. In other cases, `impl
282 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 287 /// Trait` is represented by `Ty::Opaque`.
283 self.unify_inner(ty1, ty2, 0) 288 fn insert_vars_for_impl_trait(&mut self, ty: Ty) -> Ty {
284 } 289 ty.fold(&mut |ty| match ty {
285 290 Ty::Opaque(preds) => {
286 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 291 tested_by!(insert_vars_for_impl_trait);
287 if depth > 1000 { 292 let var = self.table.new_type_var();
288 // prevent stackoverflows 293 let var_subst = Substs::builder(1).push(var.clone()).build();
289 panic!("infinite recursion in unification"); 294 self.obligations.extend(
290 } 295 preds
291 if ty1 == ty2 { 296 .iter()
292 return true; 297 .map(|pred| pred.clone().subst_bound_vars(&var_subst))
293 } 298 .filter_map(Obligation::from_predicate),
294 // try to resolve type vars first 299 );
295 let ty1 = self.resolve_ty_shallow(ty1); 300 var
296 let ty2 = self.resolve_ty_shallow(ty2);
297 match (&*ty1, &*ty2) {
298 (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => {
299 self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1)
300 }
301 _ => self.unify_inner_trivial(&ty1, &ty2),
302 }
303 }
304
305 fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
306 match (ty1, ty2) {
307 (Ty::Unknown, _) | (_, Ty::Unknown) => true,
308
309 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2)))
310 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2)))
311 | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2)))
312 | (
313 Ty::Infer(InferTy::MaybeNeverTypeVar(tv1)),
314 Ty::Infer(InferTy::MaybeNeverTypeVar(tv2)),
315 ) => {
316 // both type vars are unknown since we tried to resolve them
317 self.var_unification_table.union(*tv1, *tv2);
318 true
319 }
320
321 // The order of MaybeNeverTypeVar matters here.
322 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar.
323 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it.
324 (Ty::Infer(InferTy::TypeVar(tv)), other)
325 | (other, Ty::Infer(InferTy::TypeVar(tv)))
326 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other)
327 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv)))
328 | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_)))
329 | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv)))
330 | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_)))
331 | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => {
332 // the type var is unknown since we tried to resolve it
333 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone()));
334 true
335 } 301 }
336 302 _ => ty,
337 _ => false, 303 })
338 }
339 }
340
341 fn new_type_var(&mut self) -> Ty {
342 Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
343 }
344
345 fn new_integer_var(&mut self) -> Ty {
346 Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
347 }
348
349 fn new_float_var(&mut self) -> Ty {
350 Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
351 }
352
353 fn new_maybe_never_type_var(&mut self) -> Ty {
354 Ty::Infer(InferTy::MaybeNeverTypeVar(
355 self.var_unification_table.new_key(TypeVarValue::Unknown),
356 ))
357 } 304 }
358 305
359 /// 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.
360 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 307 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
361 match ty { 308 match ty {
362 Ty::Unknown => self.new_type_var(), 309 Ty::Unknown => self.table.new_type_var(),
363 Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(Uncertain::Unknown), .. }) => { 310 Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(Uncertain::Unknown), .. }) => {
364 self.new_integer_var() 311 self.table.new_integer_var()
365 } 312 }
366 Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(Uncertain::Unknown), .. }) => { 313 Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(Uncertain::Unknown), .. }) => {
367 self.new_float_var() 314 self.table.new_float_var()
368 } 315 }
369 _ => ty, 316 _ => ty,
370 } 317 }
@@ -402,64 +349,52 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
402 } 349 }
403 } 350 }
404 351
352 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
353 self.table.unify(ty1, ty2)
354 }
355
405 /// Resolves the type as far as currently possible, replacing type variables 356 /// Resolves the type as far as currently possible, replacing type variables
406 /// by their known types. All types returned by the infer_* functions should 357 /// by their known types. All types returned by the infer_* functions should
407 /// be resolved as far as possible, i.e. contain no type variables with 358 /// be resolved as far as possible, i.e. contain no type variables with
408 /// known type. 359 /// known type.
409 fn resolve_ty_as_possible(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 360 fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty {
410 self.resolve_obligations_as_possible(); 361 self.resolve_obligations_as_possible();
411 362
412 ty.fold(&mut |ty| match ty { 363 self.table.resolve_ty_as_possible(ty)
413 Ty::Infer(tv) => {
414 let inner = tv.to_inner();
415 if tv_stack.contains(&inner) {
416 tested_by!(type_var_cycles_resolve_as_possible);
417 // recursive type
418 return tv.fallback_value();
419 }
420 if let Some(known_ty) =
421 self.var_unification_table.inlined_probe_value(inner).known()
422 {
423 // known_ty may contain other variables that are known by now
424 tv_stack.push(inner);
425 let result = self.resolve_ty_as_possible(tv_stack, known_ty.clone());
426 tv_stack.pop();
427 result
428 } else {
429 ty
430 }
431 }
432 _ => ty,
433 })
434 } 364 }
435 365
436 /// If `ty` is a type variable with known type, returns that type;
437 /// otherwise, return ty.
438 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { 366 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> {
439 let mut ty = Cow::Borrowed(ty); 367 self.table.resolve_ty_shallow(ty)
440 // The type variable could resolve to a int/float variable. Hence try 368 }
441 // resolving up to three times; each type of variable shouldn't occur 369
442 // more than once 370 fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty {
443 for i in 0..3 { 371 self.resolve_associated_type_with_params(inner_ty, assoc_ty, &[])
444 if i > 0 { 372 }
445 tested_by!(type_var_resolves_to_int_var); 373
446 } 374 fn resolve_associated_type_with_params(
447 match &*ty { 375 &mut self,
448 Ty::Infer(tv) => { 376 inner_ty: Ty,
449 let inner = tv.to_inner(); 377 assoc_ty: Option<TypeAliasId>,
450 match self.var_unification_table.inlined_probe_value(inner).known() { 378 params: &[Ty],
451 Some(known_ty) => { 379 ) -> Ty {
452 // The known_ty can't be a type var itself 380 match assoc_ty {
453 ty = Cow::Owned(known_ty.clone()); 381 Some(res_assoc_ty) => {
454 } 382 let ty = self.table.new_type_var();
455 _ => return ty, 383 let builder = Substs::build_for_def(self.db, res_assoc_ty)
456 } 384 .push(inner_ty)
457 } 385 .fill(params.iter().cloned());
458 _ => return ty, 386 let projection = ProjectionPredicate {
387 ty: ty.clone(),
388 projection_ty: ProjectionTy {
389 associated_ty: res_assoc_ty,
390 parameters: builder.build(),
391 },
392 };
393 self.obligations.push(Obligation::Projection(projection));
394 self.resolve_ty_as_possible(ty)
459 } 395 }
396 None => Ty::Unknown,
460 } 397 }
461 log::error!("Inference variable still not resolved: {:?}", ty);
462 ty
463 } 398 }
464 399
465 /// Recurses through the given type, normalizing associated types mentioned 400 /// Recurses through the given type, normalizing associated types mentioned
@@ -469,7 +404,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
469 /// call). `make_ty` handles this already, but e.g. for field types we need 404 /// call). `make_ty` handles this already, but e.g. for field types we need
470 /// to do it as well. 405 /// to do it as well.
471 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 406 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
472 let ty = self.resolve_ty_as_possible(&mut vec![], ty); 407 let ty = self.resolve_ty_as_possible(ty);
473 ty.fold(&mut |ty| match ty { 408 ty.fold(&mut |ty| match ty {
474 Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), 409 Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty),
475 _ => ty, 410 _ => ty,
@@ -477,40 +412,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
477 } 412 }
478 413
479 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty { 414 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
480 let var = self.new_type_var(); 415 let var = self.table.new_type_var();
481 let predicate = ProjectionPredicate { projection_ty: proj_ty, ty: var.clone() }; 416 let predicate = ProjectionPredicate { projection_ty: proj_ty, ty: var.clone() };
482 let obligation = Obligation::Projection(predicate); 417 let obligation = Obligation::Projection(predicate);
483 self.obligations.push(obligation); 418 self.obligations.push(obligation);
484 var 419 var
485 } 420 }
486 421
487 /// Resolves the type completely; type variables without known type are
488 /// replaced by Ty::Unknown.
489 fn resolve_ty_completely(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
490 ty.fold(&mut |ty| match ty {
491 Ty::Infer(tv) => {
492 let inner = tv.to_inner();
493 if tv_stack.contains(&inner) {
494 tested_by!(type_var_cycles_resolve_completely);
495 // recursive type
496 return tv.fallback_value();
497 }
498 if let Some(known_ty) =
499 self.var_unification_table.inlined_probe_value(inner).known()
500 {
501 // known_ty may contain other variables that are known by now
502 tv_stack.push(inner);
503 let result = self.resolve_ty_completely(tv_stack, known_ty.clone());
504 tv_stack.pop();
505 result
506 } else {
507 tv.fallback_value()
508 }
509 }
510 _ => ty,
511 })
512 }
513
514 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { 422 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) {
515 let path = match path { 423 let path = match path {
516 Some(path) => path, 424 Some(path) => path,
@@ -519,7 +427,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
519 let resolver = &self.resolver; 427 let resolver = &self.resolver;
520 // FIXME: this should resolve assoc items as well, see this example: 428 // FIXME: this should resolve assoc items as well, see this example:
521 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 429 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
522 match resolver.resolve_path_in_type_ns_fully(self.db, &path) { 430 match resolver.resolve_path_in_type_ns_fully(self.db, path.mod_path()) {
523 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => { 431 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => {
524 let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); 432 let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into());
525 let ty = self.db.ty(strukt.into()); 433 let ty = self.db.ty(strukt.into());
@@ -547,93 +455,90 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
547 455
548 self.infer_pat(*pat, &ty, BindingMode::default()); 456 self.infer_pat(*pat, &ty, BindingMode::default());
549 } 457 }
550 self.return_ty = self.make_ty(&data.ret_type); 458 let return_ty = self.make_ty(&data.ret_type);
459 self.return_ty = self.insert_vars_for_impl_trait(return_ty);
551 } 460 }
552 461
553 fn infer_body(&mut self) { 462 fn infer_body(&mut self) {
554 self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); 463 self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
555 } 464 }
556 465
557 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { 466 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
558 let path = known::std_iter_into_iterator(); 467 let path = path![std::iter::IntoIterator];
559 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 468 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
560 self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE) 469 self.db.trait_data(trait_).associated_type_by_name(&name![Item])
561 } 470 }
562 471
563 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { 472 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
564 let path = known::std_ops_try(); 473 let path = path![std::ops::Try];
474 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
475 self.db.trait_data(trait_).associated_type_by_name(&name![Ok])
476 }
477
478 fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
479 let path = path![std::ops::Neg];
480 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
481 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
482 }
483
484 fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
485 let path = path![std::ops::Not];
565 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 486 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
566 self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE) 487 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
567 } 488 }
568 489
569 fn resolve_future_future_output(&self) -> Option<TypeAliasId> { 490 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
570 let path = known::std_future_future(); 491 let path = path![std::future::Future];
571 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 492 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
572 self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE) 493 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
573 } 494 }
574 495
575 fn resolve_boxed_box(&self) -> Option<AdtId> { 496 fn resolve_boxed_box(&self) -> Option<AdtId> {
576 let path = known::std_boxed_box(); 497 let path = path![std::boxed::Box];
577 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 498 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
578 Some(struct_.into()) 499 Some(struct_.into())
579 } 500 }
580}
581
582/// The ID of a type variable.
583#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
584pub struct TypeVarId(pub(super) u32);
585
586impl UnifyKey for TypeVarId {
587 type Value = TypeVarValue;
588 501
589 fn index(&self) -> u32 { 502 fn resolve_range_full(&self) -> Option<AdtId> {
590 self.0 503 let path = path![std::ops::RangeFull];
504 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
505 Some(struct_.into())
591 } 506 }
592 507
593 fn from_index(i: u32) -> Self { 508 fn resolve_range(&self) -> Option<AdtId> {
594 TypeVarId(i) 509 let path = path![std::ops::Range];
510 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
511 Some(struct_.into())
595 } 512 }
596 513
597 fn tag() -> &'static str { 514 fn resolve_range_inclusive(&self) -> Option<AdtId> {
598 "TypeVarId" 515 let path = path![std::ops::RangeInclusive];
516 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
517 Some(struct_.into())
599 } 518 }
600}
601
602/// The value of a type variable: either we already know the type, or we don't
603/// know it yet.
604#[derive(Clone, PartialEq, Eq, Debug)]
605pub enum TypeVarValue {
606 Known(Ty),
607 Unknown,
608}
609 519
610impl TypeVarValue { 520 fn resolve_range_from(&self) -> Option<AdtId> {
611 fn known(&self) -> Option<&Ty> { 521 let path = path![std::ops::RangeFrom];
612 match self { 522 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
613 TypeVarValue::Known(ty) => Some(ty), 523 Some(struct_.into())
614 TypeVarValue::Unknown => None,
615 }
616 } 524 }
617}
618 525
619impl UnifyValue for TypeVarValue { 526 fn resolve_range_to(&self) -> Option<AdtId> {
620 type Error = NoError; 527 let path = path![std::ops::RangeTo];
621 528 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
622 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> { 529 Some(struct_.into())
623 match (value1, value2) { 530 }
624 // We should never equate two type variables, both of which have
625 // known types. Instead, we recursively equate those types.
626 (TypeVarValue::Known(t1), TypeVarValue::Known(t2)) => panic!(
627 "equating two type variables, both of which have known types: {:?} and {:?}",
628 t1, t2
629 ),
630 531
631 // If one side is known, prefer that one. 532 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
632 (TypeVarValue::Known(..), TypeVarValue::Unknown) => Ok(value1.clone()), 533 let path = path![std::ops::RangeToInclusive];
633 (TypeVarValue::Unknown, TypeVarValue::Known(..)) => Ok(value2.clone()), 534 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
535 Some(struct_.into())
536 }
634 537
635 (TypeVarValue::Unknown, TypeVarValue::Unknown) => Ok(TypeVarValue::Unknown), 538 fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
636 } 539 let path = path![std::ops::Index];
540 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
541 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
637 } 542 }
638} 543}
639 544
@@ -643,14 +548,14 @@ impl UnifyValue for TypeVarValue {
643/// several integer types). 548/// several integer types).
644#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 549#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
645pub enum InferTy { 550pub enum InferTy {
646 TypeVar(TypeVarId), 551 TypeVar(unify::TypeVarId),
647 IntVar(TypeVarId), 552 IntVar(unify::TypeVarId),
648 FloatVar(TypeVarId), 553 FloatVar(unify::TypeVarId),
649 MaybeNeverTypeVar(TypeVarId), 554 MaybeNeverTypeVar(unify::TypeVarId),
650} 555}
651 556
652impl InferTy { 557impl InferTy {
653 fn to_inner(self) -> TypeVarId { 558 fn to_inner(self) -> unify::TypeVarId {
654 match self { 559 match self {
655 InferTy::TypeVar(ty) 560 InferTy::TypeVar(ty)
656 | InferTy::IntVar(ty) 561 | InferTy::IntVar(ty)
@@ -693,7 +598,7 @@ impl Expectation {
693} 598}
694 599
695mod diagnostics { 600mod diagnostics {
696 use hir_def::{expr::ExprId, FunctionId, HasSource, Lookup}; 601 use hir_def::{expr::ExprId, src::HasSource, FunctionId, Lookup};
697 use hir_expand::diagnostics::DiagnosticSink; 602 use hir_expand::diagnostics::DiagnosticSink;
698 603
699 use crate::{db::HirDatabase, diagnostics::NoSuchField}; 604 use crate::{db::HirDatabase, diagnostics::NoSuchField};