use the correct substs when checking struct patterns

also, make sure this is tested.
This commit is contained in:
Ariel Ben-Yehuda 2015-08-16 01:20:36 +03:00
parent 91be125899
commit 44f41063dd
3 changed files with 47 additions and 13 deletions

View File

@ -19,7 +19,6 @@ use check::{check_expr, check_expr_has_type, check_expr_with_expectation};
use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation};
use check::{check_expr_with_lvalue_pref, LvaluePreference};
use check::{instantiate_path, resolve_ty_and_def_ufcs, structurally_resolved_type};
use TypeAndSubsts;
use require_same_types;
use util::nodemap::FnvHashMap;
@ -544,14 +543,16 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
}
};
let TypeAndSubsts {
ty: pat_ty, substs: item_substs
} = pcx.fcx.instantiate_type(def.def_id(), path);
let pat_ty = pcx.fcx.instantiate_type(def.def_id(), path);
let item_substs = match pat_ty.sty {
ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
_ => tcx.sess.span_bug(pat.span, "struct variant is not an ADT")
};
demand::eqtype(fcx, pat.span, expected, pat_ty);
check_struct_pat_fields(pcx, pat.span, fields, variant, &item_substs, etc);
fcx.write_ty(pat.id, pat_ty);
fcx.write_substs(pat.id, ty::ItemSubsts { substs: item_substs });
fcx.write_substs(pat.id, ty::ItemSubsts { substs: item_substs.clone() });
}
pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,

View File

@ -1387,7 +1387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn instantiate_type(&self,
did: ast::DefId,
path: &ast::Path)
-> TypeAndSubsts<'tcx>
-> Ty<'tcx>
{
debug!("instantiate_type(did={:?}, path={:?})", did, path);
let type_scheme =
@ -1409,10 +1409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
traits::ItemObligation(did)),
&bounds);
TypeAndSubsts {
ty: self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty),
substs: substs
}
self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
}
/// Return the dict-like variant corresponding to a given `Def`.
@ -3128,9 +3125,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
}
};
let TypeAndSubsts {
ty: expr_ty, ..
} = fcx.instantiate_type(def.def_id(), path);
let expr_ty = fcx.instantiate_type(def.def_id(), path);
fcx.write_ty(expr.id, expr_ty);
check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::mem;
struct S {
x: isize,
@ -16,6 +17,13 @@ struct S {
type S2 = S;
struct S3<U,V> {
x: U,
y: V
}
type S4<U> = S3<U, char>;
fn main() {
let s = S2 {
x: 1,
@ -30,4 +38,34 @@ fn main() {
assert_eq!(y, 2);
}
}
// check that generics can be specified from the pattern
let s = S4 {
x: 4,
y: 'a'
};
match s {
S4::<u8> {
x: x,
y: y
} => {
assert_eq!(x, 4);
assert_eq!(y, 'a');
assert_eq!(mem::size_of_val(&x), 1);
}
};
// check that generics can be specified from the constructor
let s = S4::<u16> {
x: 5,
y: 'b'
};
match s {
S4 {
x: x,
y: y
} => {
assert_eq!(x, 5);
assert_eq!(y, 'b');
assert_eq!(mem::size_of_val(&x), 2);
}
};
}