diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 6e1d268de..569d46cc3 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -583,21 +583,52 @@ impl InferTy { | |||
583 | #[derive(Clone, PartialEq, Eq, Debug)] | 583 | #[derive(Clone, PartialEq, Eq, Debug)] |
584 | struct Expectation { | 584 | struct Expectation { |
585 | ty: Ty, | 585 | ty: Ty, |
586 | // FIXME: In some cases, we need to be aware whether the expectation is that | 586 | /// See the `rvalue_hint` method. |
587 | // the type match exactly what we passed, or whether it just needs to be | 587 | rvalue_hint: bool, |
588 | // coercible to the expected type. See Expectation::rvalue_hint in rustc. | ||
589 | } | 588 | } |
590 | 589 | ||
591 | impl Expectation { | 590 | impl Expectation { |
592 | /// The expectation that the type of the expression needs to equal the given | 591 | /// The expectation that the type of the expression needs to equal the given |
593 | /// type. | 592 | /// type. |
594 | fn has_type(ty: Ty) -> Self { | 593 | fn has_type(ty: Ty) -> Self { |
595 | Expectation { ty } | 594 | Expectation { ty, rvalue_hint: false } |
595 | } | ||
596 | |||
597 | /// The following explanation is copied straight from rustc: | ||
598 | /// Provides an expectation for an rvalue expression given an *optional* | ||
599 | /// hint, which is not required for type safety (the resulting type might | ||
600 | /// be checked higher up, as is the case with `&expr` and `box expr`), but | ||
601 | /// is useful in determining the concrete type. | ||
602 | /// | ||
603 | /// The primary use case is where the expected type is a fat pointer, | ||
604 | /// like `&[isize]`. For example, consider the following statement: | ||
605 | /// | ||
606 | /// let x: &[isize] = &[1, 2, 3]; | ||
607 | /// | ||
608 | /// In this case, the expected type for the `&[1, 2, 3]` expression is | ||
609 | /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the | ||
610 | /// expectation `ExpectHasType([isize])`, that would be too strong -- | ||
611 | /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`. | ||
612 | /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced | ||
613 | /// to the type `&[isize]`. Therefore, we propagate this more limited hint, | ||
614 | /// which still is useful, because it informs integer literals and the like. | ||
615 | /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169 | ||
616 | /// for examples of where this comes up,. | ||
617 | fn rvalue_hint(ty: Ty) -> Self { | ||
618 | Expectation { ty, rvalue_hint: true } | ||
596 | } | 619 | } |
597 | 620 | ||
598 | /// This expresses no expectation on the type. | 621 | /// This expresses no expectation on the type. |
599 | fn none() -> Self { | 622 | fn none() -> Self { |
600 | Expectation { ty: Ty::Unknown } | 623 | Expectation { ty: Ty::Unknown, rvalue_hint: false } |
624 | } | ||
625 | |||
626 | fn coercion_target(&self) -> &Ty { | ||
627 | if self.rvalue_hint { | ||
628 | &Ty::Unknown | ||
629 | } else { | ||
630 | &self.ty | ||
631 | } | ||
601 | } | 632 | } |
602 | } | 633 | } |
603 | 634 | ||