Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/coerce.rs')
-rw-r--r--crates/hir-ty/src/infer/coerce.rs28
1 files changed, 21 insertions, 7 deletions
diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs
index e9c94449cf..05a476f632 100644
--- a/crates/hir-ty/src/infer/coerce.rs
+++ b/crates/hir-ty/src/infer/coerce.rs
@@ -50,6 +50,13 @@ fn success(
Ok(InferOk { goals, value: (adj, target) })
}
+pub(super) enum CoercionCause {
+ // FIXME: Make better use of this. Right now things like return and break without a value
+ // use it to point to themselves, causing us to report a mismatch on those expressions even
+ // though technically they themselves are `!`
+ Expr(ExprId),
+}
+
#[derive(Clone, Debug)]
pub(super) struct CoerceMany {
expected_ty: Ty,
@@ -90,8 +97,12 @@ impl CoerceMany {
}
}
- pub(super) fn coerce_forced_unit(&mut self, ctx: &mut InferenceContext<'_>) {
- self.coerce(ctx, None, &ctx.result.standard_types.unit.clone())
+ pub(super) fn coerce_forced_unit(
+ &mut self,
+ ctx: &mut InferenceContext<'_>,
+ cause: CoercionCause,
+ ) {
+ self.coerce(ctx, None, &ctx.result.standard_types.unit.clone(), cause)
}
/// Merge two types from different branches, with possible coercion.
@@ -106,6 +117,7 @@ impl CoerceMany {
ctx: &mut InferenceContext<'_>,
expr: Option<ExprId>,
expr_ty: &Ty,
+ cause: CoercionCause,
) {
let expr_ty = ctx.resolve_ty_shallow(expr_ty);
self.expected_ty = ctx.resolve_ty_shallow(&self.expected_ty);
@@ -153,11 +165,13 @@ impl CoerceMany {
} else if let Ok(res) = ctx.coerce(expr, &self.merged_ty(), &expr_ty) {
self.final_ty = Some(res);
} else {
- if let Some(id) = expr {
- ctx.result.type_mismatches.insert(
- id.into(),
- TypeMismatch { expected: self.merged_ty(), actual: expr_ty.clone() },
- );
+ match cause {
+ CoercionCause::Expr(id) => {
+ ctx.result.type_mismatches.insert(
+ id.into(),
+ TypeMismatch { expected: self.merged_ty(), actual: expr_ty.clone() },
+ );
+ }
}
cov_mark::hit!(coerce_merge_fail_fallback);
}