Skip to content

Commit

Permalink
Factor write_ty out of more pattern-checking functions
Browse files Browse the repository at this point in the history
  • Loading branch information
canndrew committed Sep 5, 2016
1 parent c5ff28c commit 1749fda
Showing 1 changed file with 20 additions and 22 deletions.
42 changes: 20 additions & 22 deletions src/librustc_typeck/check/_match.rs
Expand Up @@ -150,14 +150,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.write_ty(pat.id, typ);
}
PatKind::TupleStruct(ref path, ref subpats, ddpos) => {
self.check_pat_tuple_struct(pat, path, &subpats, ddpos, expected);
let pat_ty = self.check_pat_tuple_struct(pat, path, &subpats, ddpos, expected);
write_ty(pat.id, pat_ty);
}
PatKind::Path(ref opt_qself, ref path) => {
let opt_qself_ty = opt_qself.as_ref().map(|qself| self.to_ty(&qself.ty));
self.check_pat_path(pat, opt_qself_ty, path, expected);
let pat_ty = self.check_pat_path(pat, opt_qself_ty, path, expected);
write_ty(pat.id, pat_ty);
}
PatKind::Struct(ref path, ref fields, etc) => {
self.check_pat_struct(pat, path, fields, etc, expected);
let pat_ty = self.check_pat_struct(pat, path, fields, etc, expected);
write_ty(pat.id, pat_ty);
}
PatKind::Tuple(ref elements, ddpos) => {
let mut expected_len = elements.len();
Expand Down Expand Up @@ -481,40 +484,38 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
path: &hir::Path,
fields: &'gcx [Spanned<hir::FieldPat>],
etc: bool,
expected: Ty<'tcx>)
expected: Ty<'tcx>) -> Ty<'tcx>
{
// Resolve the path and check the definition for errors.
let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(path, pat.id,
pat.span) {
variant_ty
} else {
self.write_error(pat.id);
for field in fields {
self.check_pat(&field.node.pat, self.tcx.types.err);
}
return;
return tcx.types.err;
};
self.write_ty(pat.id, pat_ty);

// Type check the path.
self.demand_eqtype(pat.span, expected, pat_ty);

// Type check subpatterns.
self.check_struct_pat_fields(pat_ty, pat.span, variant, fields, etc);
pat_ty
}

fn check_pat_path(&self,
pat: &hir::Pat,
opt_self_ty: Option<Ty<'tcx>>,
path: &hir::Path,
expected: Ty<'tcx>)
expected: Ty<'tcx>) -> Ty<'tcx>
{
let tcx = self.tcx;
let report_unexpected_def = || {
span_err!(tcx.sess, pat.span, E0533,
"`{}` does not name a unit variant, unit struct or a constant",
pprust::path_to_string(path));
self.write_error(pat.id);
};

// Resolve the path and check the definition for errors.
Expand All @@ -523,18 +524,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
match def {
Def::Err => {
self.set_tainted_by_errors();
self.write_error(pat.id);
return;
return tcx.types.err;
}
Def::Method(..) => {
report_unexpected_def();
return;
return tcx.types.err;
}
Def::Variant(..) | Def::Struct(..) => {
let variant = tcx.expect_variant_def(def);
if variant.kind != VariantKind::Unit {
report_unexpected_def();
return;
return tcx.types.err;
}
}
Def::Const(..) | Def::AssociatedConst(..) => {} // OK
Expand All @@ -543,20 +543,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {

// Type check the path.
let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
self.write_ty(pat.id, pat_ty);
self.demand_suptype(pat.span, expected, pat_ty);
pat_ty
}

fn check_pat_tuple_struct(&self,
pat: &hir::Pat,
path: &hir::Path,
subpats: &'gcx [P<hir::Pat>],
ddpos: Option<usize>,
expected: Ty<'tcx>)
expected: Ty<'tcx>) -> Ty<'tcx>
{
let tcx = self.tcx;
let on_error = || {
self.write_error(pat.id);
for pat in subpats {
self.check_pat(&pat, tcx.types.err);
}
Expand All @@ -580,11 +579,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Def::Err => {
self.set_tainted_by_errors();
on_error();
return;
return tcx.types.err;
}
Def::Const(..) | Def::AssociatedConst(..) | Def::Method(..) => {
report_unexpected_def(false);
return;
return tcx.types.err;
}
Def::Variant(..) | Def::Struct(..) => {
tcx.expect_variant_def(def)
Expand All @@ -597,21 +596,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
report_unexpected_def(true);
} else if variant.kind != VariantKind::Tuple {
report_unexpected_def(false);
return;
return tcx.types.err;
}

// Type check the path.
let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
self.write_ty(pat.id, pat_ty);

let pat_ty = if pat_ty.is_fn() {
// Replace constructor type with constructed type for tuple struct patterns.
tcx.no_late_bound_regions(&pat_ty.fn_ret()).unwrap()
} else {
// Leave the type as is for unit structs (backward compatibility).
pat_ty
};
self.write_ty(pat.id, pat_ty);
self.demand_eqtype(pat.span, expected, pat_ty);

// Type check subpatterns.
Expand Down Expand Up @@ -644,7 +640,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
variant.fields.len(), fields_ending, subpats.len()))
.emit();
on_error();
return tcx.types.err;
}
pat_ty
}

fn check_struct_pat_fields(&self,
Expand Down

0 comments on commit 1749fda

Please sign in to comment.