Replace Expectation by &Ty in infer_pat method

This commit is contained in:
Marcus Klaas de Vries 2019-01-18 15:17:11 +01:00 committed by Aleksey Kladov
parent f9a6050034
commit 4277f420aa

View file

@ -902,7 +902,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
.get(i) .get(i)
.and_then(|field| field.ty(self.db)) .and_then(|field| field.ty(self.db))
.unwrap_or(Ty::Unknown); .unwrap_or(Ty::Unknown);
self.infer_pat(subpat, &Expectation::has_type(expected_ty)); self.infer_pat(subpat, &expected_ty);
} }
ty ty
@ -918,45 +918,45 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
let expected_ty = matching_field let expected_ty = matching_field
.and_then(|field| field.ty(self.db)) .and_then(|field| field.ty(self.db))
.unwrap_or(Ty::Unknown); .unwrap_or(Ty::Unknown);
self.infer_pat(subpat.pat, &Expectation::has_type(expected_ty)); self.infer_pat(subpat.pat, &expected_ty);
} }
ty ty
} }
fn infer_pat(&mut self, pat: PatId, expected: &Expectation) -> Ty { fn infer_pat(&mut self, pat: PatId, expected: &Ty) -> Ty {
let body = Arc::clone(&self.body); // avoid borrow checker problem let body = Arc::clone(&self.body); // avoid borrow checker problem
let ty = match &body[pat] { let ty = match &body[pat] {
Pat::Tuple(ref args) => { Pat::Tuple(ref args) => {
// this can probably be done without cloning/ collecting let expectations = match *expected {
let expectations = match expected.ty { Ty::Tuple(ref tuple_args) => &**tuple_args,
Ty::Tuple(ref tuple_args) if args.len() == tuple_args.len() => { _ => &[],
tuple_args.iter().cloned().collect()
}
_ => vec![Ty::Unknown; args.len()],
}; };
let expectations_iter = expectations
.into_iter()
.chain(std::iter::repeat(&Ty::Unknown));
let inner_tys = args let inner_tys = args
.iter() .iter()
.zip(expectations.into_iter()) .zip(expectations_iter)
.map(|(&pat, ty)| self.infer_pat(pat, &Expectation::has_type(ty))) .map(|(&pat, ty)| self.infer_pat(pat, ty))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into(); .into();
Ty::Tuple(inner_tys) Ty::Tuple(inner_tys)
} }
Pat::Ref { pat, mutability } => { Pat::Ref { pat, mutability } => {
let expectation = match expected.ty { let expectation = match *expected {
Ty::Ref(ref sub_ty, exp_mut) => { Ty::Ref(ref sub_ty, exp_mut) => {
if *mutability != exp_mut { if *mutability != exp_mut {
// TODO: emit type error? // TODO: emit type error?
} }
Expectation::has_type((&**sub_ty).clone()) &**sub_ty
} }
_ => Expectation::none(), _ => &Ty::Unknown,
}; };
let subty = self.infer_pat(*pat, &expectation); let subty = self.infer_pat(*pat, expectation);
Ty::Ref(subty.into(), *mutability) Ty::Ref(subty.into(), *mutability)
} }
Pat::TupleStruct { Pat::TupleStruct {
@ -980,7 +980,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
let subty = if let Some(subpat) = subpat { let subty = if let Some(subpat) = subpat {
self.infer_pat(*subpat, expected) self.infer_pat(*subpat, expected)
} else { } else {
expected.ty.clone() expected.clone()
}; };
match mode { match mode {
@ -993,7 +993,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
}; };
// use a new type variable if we got Ty::Unknown here // use a new type variable if we got Ty::Unknown here
let ty = self.insert_type_vars_shallow(ty); let ty = self.insert_type_vars_shallow(ty);
self.unify(&ty, &expected.ty); self.unify(&ty, expected);
let ty = self.resolve_ty_as_possible(ty); let ty = self.resolve_ty_as_possible(ty);
self.write_pat_ty(pat, ty.clone()); self.write_pat_ty(pat, ty.clone());
ty ty
@ -1040,7 +1040,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
pat, pat,
} => { } => {
let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); let _iterable_ty = self.infer_expr(*iterable, &Expectation::none());
self.infer_pat(*pat, &Expectation::none()); self.infer_pat(*pat, &Ty::Unknown);
self.infer_expr(*body, &Expectation::has_type(Ty::unit())); self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
Ty::unit() Ty::unit()
} }
@ -1054,9 +1054,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) {
let expected = if let Some(type_ref) = arg_type { let expected = if let Some(type_ref) = arg_type {
let ty = self.make_ty(type_ref); let ty = self.make_ty(type_ref);
Expectation::has_type(ty) ty
} else { } else {
Expectation::none() Ty::Unknown
}; };
self.infer_pat(*arg_pat, &expected); self.infer_pat(*arg_pat, &expected);
} }
@ -1126,11 +1126,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
expected.clone() expected.clone()
}; };
let input_ty = self.infer_expr(*expr, &Expectation::none()); let input_ty = self.infer_expr(*expr, &Expectation::none());
let pat_expectation = Expectation::has_type(input_ty);
for arm in arms { for arm in arms {
for &pat in &arm.pats { for &pat in &arm.pats {
let _pat_ty = self.infer_pat(pat, &pat_expectation); let _pat_ty = self.infer_pat(pat, &input_ty);
} }
// TODO type the guard // TODO type the guard
self.infer_expr(arm.expr, &expected); self.infer_expr(arm.expr, &expected);
@ -1323,7 +1322,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
decl_ty decl_ty
}; };
self.infer_pat(*pat, &Expectation::has_type(ty)); self.infer_pat(*pat, &ty);
} }
Statement::Expr(expr) => { Statement::Expr(expr) => {
self.infer_expr(*expr, &Expectation::none()); self.infer_expr(*expr, &Expectation::none());
@ -1344,7 +1343,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
let ty = self.make_ty(type_ref); let ty = self.make_ty(type_ref);
let ty = self.insert_type_vars(ty); let ty = self.insert_type_vars(ty);
self.infer_pat(*pat, &Expectation::has_type(ty)); self.infer_pat(*pat, &ty);
} }
self.return_ty = { self.return_ty = {
let ty = self.make_ty(signature.ret_type()); let ty = self.make_ty(signature.ret_type());