typeck/pat.rs: extract check_pat_tuple
.
This commit is contained in:
parent
c16248d3a1
commit
3a51caa648
@ -105,48 +105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expected_ty
|
||||
}
|
||||
PatKind::Tuple(ref elements, ddpos) => {
|
||||
let mut expected_len = elements.len();
|
||||
if ddpos.is_some() {
|
||||
// Require known type only when `..` is present.
|
||||
if let ty::Tuple(ref tys) =
|
||||
self.structurally_resolved_type(pat.span, expected).sty {
|
||||
expected_len = tys.len();
|
||||
}
|
||||
}
|
||||
let max_len = cmp::max(expected_len, elements.len());
|
||||
|
||||
let element_tys_iter = (0..max_len).map(|_| {
|
||||
Kind::from(self.next_ty_var(
|
||||
// FIXME: `MiscVariable` for now -- obtaining the span and name information
|
||||
// from all tuple elements isn't trivial.
|
||||
TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeInference,
|
||||
span: pat.span,
|
||||
},
|
||||
))
|
||||
});
|
||||
let element_tys = tcx.mk_substs(element_tys_iter);
|
||||
let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
|
||||
if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) {
|
||||
err.emit();
|
||||
// Walk subpatterns with an expected type of `err` in this case to silence
|
||||
// further errors being emitted when using the bindings. #50333
|
||||
let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
|
||||
for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
|
||||
self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
|
||||
}
|
||||
tcx.mk_tup(element_tys_iter)
|
||||
} else {
|
||||
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
|
||||
self.check_pat_walk(
|
||||
elem,
|
||||
&element_tys[i].expect_ty(),
|
||||
def_bm,
|
||||
discrim_span,
|
||||
);
|
||||
}
|
||||
pat_ty
|
||||
}
|
||||
self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, discrim_span)
|
||||
}
|
||||
PatKind::Box(ref inner) => {
|
||||
let inner_ty = self.next_ty_var(TypeVariableOrigin {
|
||||
@ -807,7 +766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pat.hir_id);
|
||||
if !pat_ty.is_fn() {
|
||||
report_unexpected_res(res);
|
||||
return self.tcx.types.err;
|
||||
return tcx.types.err;
|
||||
}
|
||||
|
||||
let variant = match res {
|
||||
@ -833,8 +792,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
|
||||
|
||||
// Type-check subpatterns.
|
||||
if subpats.len() == variant.fields.len() ||
|
||||
subpats.len() < variant.fields.len() && ddpos.is_some() {
|
||||
if subpats.len() == variant.fields.len()
|
||||
|| subpats.len() < variant.fields.len() && ddpos.is_some()
|
||||
{
|
||||
let substs = match pat_ty.sty {
|
||||
ty::Adt(_, substs) => substs,
|
||||
_ => bug!("unexpected pattern type {:?}", pat_ty),
|
||||
@ -861,6 +821,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pat_ty
|
||||
}
|
||||
|
||||
fn check_pat_tuple(
|
||||
&self,
|
||||
span: Span,
|
||||
elements: &'tcx [P<hir::Pat>],
|
||||
ddpos: Option<usize>,
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: ty::BindingMode,
|
||||
discrim_span: Option<Span>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let mut expected_len = elements.len();
|
||||
if ddpos.is_some() {
|
||||
// Require known type only when `..` is present.
|
||||
if let ty::Tuple(ref tys) = self.structurally_resolved_type(span, expected).sty {
|
||||
expected_len = tys.len();
|
||||
}
|
||||
}
|
||||
let max_len = cmp::max(expected_len, elements.len());
|
||||
|
||||
let element_tys_iter = (0..max_len).map(|_| {
|
||||
Kind::from(self.next_ty_var(
|
||||
// FIXME: `MiscVariable` for now -- obtaining the span and name information
|
||||
// from all tuple elements isn't trivial.
|
||||
TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeInference,
|
||||
span,
|
||||
},
|
||||
))
|
||||
});
|
||||
let element_tys = tcx.mk_substs(element_tys_iter);
|
||||
let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
|
||||
if let Some(mut err) = self.demand_eqtype_diag(span, expected, pat_ty) {
|
||||
err.emit();
|
||||
// Walk subpatterns with an expected type of `err` in this case to silence
|
||||
// further errors being emitted when using the bindings. #50333
|
||||
let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
|
||||
for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
|
||||
self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
|
||||
}
|
||||
tcx.mk_tup(element_tys_iter)
|
||||
} else {
|
||||
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
|
||||
self.check_pat_walk(
|
||||
elem,
|
||||
&element_tys[i].expect_ty(),
|
||||
def_bm,
|
||||
discrim_span,
|
||||
);
|
||||
}
|
||||
pat_ty
|
||||
}
|
||||
}
|
||||
|
||||
fn check_struct_pat_fields(
|
||||
&self,
|
||||
adt_ty: Ty<'tcx>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user