Check type when struct is matched against enum-like pattern

Previously check always succeeded because struct type was derived from
the matched expression, not the matched pattern.
This commit is contained in:
Seo Sanghyeon 2013-02-20 01:43:15 +09:00
parent 67ee95e943
commit a29023e9b2
3 changed files with 23 additions and 3 deletions

View File

@ -2823,7 +2823,7 @@ pub pure fn ty_fn_ret(fty: t) -> t {
}
}
fn is_fn_ty(fty: t) -> bool {
pub fn is_fn_ty(fty: t) -> bool {
match get(fty).sty {
ty_bare_fn(_) => true,
ty_closure(_) => true,

View File

@ -92,7 +92,7 @@ pub fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
match structure_of(pcx.fcx, pat.span, expected) {
ty::ty_enum(_, ref expected_substs) => {
// Lookup the enum and variant def ids:
let v_def = lookup_def(pcx.fcx, path.span, pat.id);
let v_def = lookup_def(pcx.fcx, pat.span, pat.id);
let v_def_ids = ast_util::variant_def_ids(v_def);
// Assign the pattern the type of the *enum*, not the variant.
@ -125,8 +125,17 @@ pub fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
kind_name = "variant";
}
ty::ty_struct(struct_def_id, ref expected_substs) => {
// Lookup the struct ctor def id
let s_def = lookup_def(pcx.fcx, pat.span, pat.id);
let s_def_id = ast_util::def_id_of_def(s_def);
// Assign the pattern the type of the struct.
let struct_tpt = ty::lookup_item_type(tcx, struct_def_id);
let ctor_tpt = ty::lookup_item_type(tcx, s_def_id);
let struct_tpt = if ty::is_fn_ty(ctor_tpt.ty) {
{ty: ty::ty_fn_ret(ctor_tpt.ty), ..ctor_tpt}
} else {
ctor_tpt
};
instantiate_path(pcx.fcx, path, struct_tpt, pat.span, pat.id,
pcx.block_region);

View File

@ -0,0 +1,11 @@
// error-pattern: mismatched types
struct S { a: int }
enum E { C(int) }
fn main() {
match S { a: 1 } {
C(_) => (),
_ => ()
}
}