diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 3757c55a162f..0ac9e0a9c59a 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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>, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 74df7d8e58a1..7c35aea68503 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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, diff --git a/src/test/run-pass/struct-aliases.rs b/src/test/run-pass/struct-aliases.rs index 7107243d760a..f1337a5b0797 100644 --- a/src/test/run-pass/struct-aliases.rs +++ b/src/test/run-pass/struct-aliases.rs @@ -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 { + x: U, + y: V +} + +type S4 = S3; + 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:: { + 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:: { + 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); + } + }; }