diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_ty/src/infer.rs | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (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.rs | 361 |
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; | |||
18 | use std::ops::Index; | 18 | use std::ops::Index; |
19 | use std::sync::Arc; | 19 | use std::sync::Arc; |
20 | 20 | ||
21 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | ||
22 | use rustc_hash::FxHashMap; | 21 | use rustc_hash::FxHashMap; |
23 | 22 | ||
24 | use hir_def::{ | 23 | use 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 | }; |
33 | use hir_expand::{diagnostics::DiagnosticSink, name}; | 32 | use hir_expand::{diagnostics::DiagnosticSink, name::name}; |
34 | use ra_arena::map::ArenaMap; | 33 | use ra_arena::map::ArenaMap; |
35 | use ra_prof::profile; | 34 | use ra_prof::profile; |
36 | use test_utils::tested_by; | 35 | use test_utils::tested_by; |
@@ -43,6 +42,8 @@ use super::{ | |||
43 | }; | 42 | }; |
44 | use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; | 43 | use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; |
45 | 44 | ||
45 | pub(crate) use unify::unify; | ||
46 | |||
46 | macro_rules! ty_app { | 47 | macro_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)] | ||
584 | pub struct TypeVarId(pub(super) u32); | ||
585 | |||
586 | impl 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)] | ||
605 | pub enum TypeVarValue { | ||
606 | Known(Ty), | ||
607 | Unknown, | ||
608 | } | ||
609 | 519 | ||
610 | impl 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 | ||
619 | impl 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)] |
645 | pub enum InferTy { | 550 | pub 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 | ||
652 | impl InferTy { | 557 | impl 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 | ||
695 | mod diagnostics { | 600 | mod 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}; |