Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/pat.rs')
-rw-r--r--crates/hir-ty/src/infer/pat.rs57
1 files changed, 28 insertions, 29 deletions
diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs
index 09a4d998ee..1b354935a5 100644
--- a/crates/hir-ty/src/infer/pat.rs
+++ b/crates/hir-ty/src/infer/pat.rs
@@ -2,21 +2,22 @@
use std::iter::repeat_with;
-use chalk_ir::Mutability;
use hir_def::{
body::Body,
hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId},
path::Path,
};
use hir_expand::name::Name;
+use stdx::TupleExt;
use crate::{
consteval::{try_const_usize, usize_const},
+ error_lifetime,
infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
lower::lower_to_chalk_mutability,
primitive::UintTy,
- static_lifetime, InferenceDiagnostic, Interner, Scalar, Substitution, Ty, TyBuilder, TyExt,
- TyKind,
+ static_lifetime, InferenceDiagnostic, Interner, Mutability, Scalar, Substitution, Ty,
+ TyBuilder, TyExt, TyKind,
};
/// Used to generalize patterns and assignee expressions.
@@ -89,9 +90,6 @@ impl InferenceContext<'_> {
self.unify(&ty, expected);
- let substs =
- ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
-
match def {
_ if subs.is_empty() => {}
Some(def) => {
@@ -108,8 +106,10 @@ impl InferenceContext<'_> {
let pre_iter = pre.iter().enumerate();
let post_iter = (post_idx_offset..).zip(post.iter());
+ let substs = ty.as_adt().map(TupleExt::tail);
+
for (i, &subpat) in pre_iter.chain(post_iter) {
- let field_def = {
+ let expected_ty = {
match variant_data.field(&Name::new_tuple_field(i)) {
Some(local_id) => {
if !visibilities[local_id]
@@ -117,17 +117,17 @@ impl InferenceContext<'_> {
{
// FIXME(DIAGNOSE): private tuple field
}
- Some(local_id)
+ let f = field_types[local_id].clone();
+ let expected_ty = match substs {
+ Some(substs) => f.substitute(Interner, substs),
+ None => f.substitute(Interner, &Substitution::empty(Interner)),
+ };
+ self.normalize_associated_types_in(expected_ty)
}
- None => None,
+ None => self.err_ty(),
}
};
- let expected_ty = field_def.map_or(self.err_ty(), |f| {
- field_types[f].clone().substitute(Interner, &substs)
- });
- let expected_ty = self.normalize_associated_types_in(expected_ty);
-
T::infer(self, subpat, &expected_ty, default_bm);
}
}
@@ -149,7 +149,7 @@ impl InferenceContext<'_> {
expected: &Ty,
default_bm: T::BindingMode,
id: T,
- subs: impl Iterator<Item = (Name, T)> + ExactSizeIterator,
+ subs: impl ExactSizeIterator<Item = (Name, T)>,
) -> Ty {
let (ty, def) = self.resolve_variant(path, false);
if let Some(variant) = def {
@@ -158,9 +158,6 @@ impl InferenceContext<'_> {
self.unify(&ty, expected);
- let substs =
- ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
-
match def {
_ if subs.len() == 0 => {}
Some(def) => {
@@ -168,8 +165,10 @@ impl InferenceContext<'_> {
let variant_data = def.variant_data(self.db.upcast());
let visibilities = self.db.field_visibilities(def);
+ let substs = ty.as_adt().map(TupleExt::tail);
+
for (name, inner) in subs {
- let field_def = {
+ let expected_ty = {
match variant_data.field(&name) {
Some(local_id) => {
if !visibilities[local_id]
@@ -180,23 +179,23 @@ impl InferenceContext<'_> {
private: true,
});
}
- Some(local_id)
+ let f = field_types[local_id].clone();
+ let expected_ty = match substs {
+ Some(substs) => f.substitute(Interner, substs),
+ None => f.substitute(Interner, &Substitution::empty(Interner)),
+ };
+ self.normalize_associated_types_in(expected_ty)
}
None => {
self.push_diagnostic(InferenceDiagnostic::NoSuchField {
field: inner.into(),
private: false,
});
- None
+ self.err_ty()
}
}
};
- let expected_ty = field_def.map_or(self.err_ty(), |f| {
- field_types[f].clone().substitute(Interner, &substs)
- });
- let expected_ty = self.normalize_associated_types_in(expected_ty);
-
T::infer(self, inner, &expected_ty, default_bm);
}
}
@@ -396,14 +395,14 @@ impl InferenceContext<'_> {
None => {
let inner_ty = self.table.new_type_var();
let ref_ty =
- TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()).intern(Interner);
+ TyKind::Ref(mutability, error_lifetime(), inner_ty.clone()).intern(Interner);
// Unification failure will be reported by the caller.
self.unify(&ref_ty, expected);
inner_ty
}
};
let subty = self.infer_pat(inner_pat, &expectation, default_bm);
- TyKind::Ref(mutability, static_lifetime(), subty).intern(Interner)
+ TyKind::Ref(mutability, error_lifetime(), subty).intern(Interner)
}
fn infer_bind_pat(
@@ -430,7 +429,7 @@ impl InferenceContext<'_> {
let bound_ty = match mode {
BindingMode::Ref(mutability) => {
- TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()).intern(Interner)
+ TyKind::Ref(mutability, error_lifetime(), inner_ty.clone()).intern(Interner)
}
BindingMode::Move => inner_ty.clone(),
};