use the correct substs when checking struct patterns
also, make sure this is tested.
This commit is contained in:
parent
91be125899
commit
44f41063dd
@ -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>,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user