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.rs48
1 files changed, 23 insertions, 25 deletions
diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs
index 440ffa3357..1b354935a5 100644
--- a/crates/hir-ty/src/infer/pat.rs
+++ b/crates/hir-ty/src/infer/pat.rs
@@ -2,13 +2,13 @@
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},
@@ -16,8 +16,8 @@ use crate::{
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.
@@ -90,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) => {
@@ -109,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]
@@ -118,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);
}
}
@@ -159,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) => {
@@ -169,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]
@@ -181,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);
}
}