Skip to content

Commit 44f4106

Browse files
committed
use the correct substs when checking struct patterns
also, make sure this is tested.
1 parent 91be125 commit 44f4106

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

src/librustc_typeck/check/_match.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use check::{check_expr, check_expr_has_type, check_expr_with_expectation};
1919
use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation};
2020
use check::{check_expr_with_lvalue_pref, LvaluePreference};
2121
use check::{instantiate_path, resolve_ty_and_def_ufcs, structurally_resolved_type};
22-
use TypeAndSubsts;
2322
use require_same_types;
2423
use util::nodemap::FnvHashMap;
2524

@@ -544,14 +543,16 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
544543
}
545544
};
546545

547-
let TypeAndSubsts {
548-
ty: pat_ty, substs: item_substs
549-
} = pcx.fcx.instantiate_type(def.def_id(), path);
546+
let pat_ty = pcx.fcx.instantiate_type(def.def_id(), path);
547+
let item_substs = match pat_ty.sty {
548+
ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
549+
_ => tcx.sess.span_bug(pat.span, "struct variant is not an ADT")
550+
};
550551
demand::eqtype(fcx, pat.span, expected, pat_ty);
551552
check_struct_pat_fields(pcx, pat.span, fields, variant, &item_substs, etc);
552553

553554
fcx.write_ty(pat.id, pat_ty);
554-
fcx.write_substs(pat.id, ty::ItemSubsts { substs: item_substs });
555+
fcx.write_substs(pat.id, ty::ItemSubsts { substs: item_substs.clone() });
555556
}
556557

557558
pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,

src/librustc_typeck/check/mod.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -1387,7 +1387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13871387
pub fn instantiate_type(&self,
13881388
did: ast::DefId,
13891389
path: &ast::Path)
1390-
-> TypeAndSubsts<'tcx>
1390+
-> Ty<'tcx>
13911391
{
13921392
debug!("instantiate_type(did={:?}, path={:?})", did, path);
13931393
let type_scheme =
@@ -1409,10 +1409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14091409
traits::ItemObligation(did)),
14101410
&bounds);
14111411

1412-
TypeAndSubsts {
1413-
ty: self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty),
1414-
substs: substs
1415-
}
1412+
self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
14161413
}
14171414

14181415
/// 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>,
31283125
}
31293126
};
31303127

3131-
let TypeAndSubsts {
3132-
ty: expr_ty, ..
3133-
} = fcx.instantiate_type(def.def_id(), path);
3128+
let expr_ty = fcx.instantiate_type(def.def_id(), path);
31343129
fcx.write_ty(expr.id, expr_ty);
31353130

31363131
check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,

src/test/run-pass/struct-aliases.rs

+38
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use std::mem;
1112

1213
struct S {
1314
x: isize,
@@ -16,6 +17,13 @@ struct S {
1617

1718
type S2 = S;
1819

20+
struct S3<U,V> {
21+
x: U,
22+
y: V
23+
}
24+
25+
type S4<U> = S3<U, char>;
26+
1927
fn main() {
2028
let s = S2 {
2129
x: 1,
@@ -30,4 +38,34 @@ fn main() {
3038
assert_eq!(y, 2);
3139
}
3240
}
41+
// check that generics can be specified from the pattern
42+
let s = S4 {
43+
x: 4,
44+
y: 'a'
45+
};
46+
match s {
47+
S4::<u8> {
48+
x: x,
49+
y: y
50+
} => {
51+
assert_eq!(x, 4);
52+
assert_eq!(y, 'a');
53+
assert_eq!(mem::size_of_val(&x), 1);
54+
}
55+
};
56+
// check that generics can be specified from the constructor
57+
let s = S4::<u16> {
58+
x: 5,
59+
y: 'b'
60+
};
61+
match s {
62+
S4 {
63+
x: x,
64+
y: y
65+
} => {
66+
assert_eq!(x, 5);
67+
assert_eq!(y, 'b');
68+
assert_eq!(mem::size_of_val(&x), 2);
69+
}
70+
};
3371
}

0 commit comments

Comments
 (0)