Skip to content

Commit ba98228

Browse files
committed
clean-up ExprStruct and PatStruct type-checking
This fixes the crazy "transparent aliases" bug, which I hope nobody relied on.
1 parent b87c292 commit ba98228

File tree

5 files changed

+145
-245
lines changed

5 files changed

+145
-245
lines changed

src/librustc_typeck/check/_match.rs

+17-47
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ 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;
2223
use require_same_types;
2324
use util::nodemap::FnvHashMap;
2425

@@ -526,62 +527,31 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
526527
etc: bool, expected: Ty<'tcx>) {
527528
let fcx = pcx.fcx;
528529
let tcx = pcx.fcx.ccx.tcx;
529-
let report_nonstruct = || {
530-
let name = pprust::path_to_string(path);
531-
span_err!(tcx.sess, pat.span, E0163,
532-
"`{}` does not name a struct or a struct variant", name);
533-
fcx.write_error(pat.id);
534-
535-
for field in fields {
536-
check_pat(pcx, &field.node.pat, tcx.types.err);
537-
}
538-
};
539530

540531
let def = tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
541-
let (adt_def, variant) = match def {
542-
def::DefTy(did, _) | def::DefStruct(did) => {
543-
match tcx.lookup_item_type(did).ty.sty {
544-
ty::TyStruct(struct_def, _) =>
545-
(struct_def, struct_def.struct_variant()),
546-
_ => {
547-
report_nonstruct();
548-
return;
549-
}
550-
}
551-
}
552-
def::DefVariant(eid, vid, true) => {
553-
match tcx.lookup_item_type(vid).ty.sty {
554-
ty::TyEnum(enum_def, _) if enum_def.did == eid => {
555-
(enum_def, enum_def.variant_with_id(vid))
556-
}
557-
_ => tcx.sess.span_bug(pat.span, "variant's type is not its enum")
532+
let variant = match fcx.def_struct_variant(def) {
533+
Some((_, variant)) => variant,
534+
None => {
535+
let name = pprust::path_to_string(path);
536+
span_err!(tcx.sess, pat.span, E0163,
537+
"`{}` does not name a struct or a struct variant", name);
538+
fcx.write_error(pat.id);
539+
540+
for field in fields {
541+
check_pat(pcx, &field.node.pat, tcx.types.err);
558542
}
559-
}
560-
_ => {
561-
report_nonstruct();
562543
return;
563544
}
564545
};
565546

566-
instantiate_path(pcx.fcx,
567-
&path.segments,
568-
adt_def.type_scheme(tcx),
569-
&adt_def.predicates(tcx),
570-
None,
571-
def,
572-
pat.span,
573-
pat.id);
574-
575-
let pat_ty = fcx.node_ty(pat.id);
547+
let TypeAndSubsts {
548+
ty: pat_ty, substs: item_substs
549+
} = pcx.fcx.instantiate_type(def.def_id(), path);
576550
demand::eqtype(fcx, pat.span, expected, pat_ty);
577-
578-
let item_substs = fcx
579-
.item_substs()
580-
.get(&pat.id)
581-
.map(|substs| substs.substs.clone())
582-
.unwrap_or_else(|| Substs::empty());
583-
584551
check_struct_pat_fields(pcx, pat.span, fields, variant, &item_substs, etc);
552+
553+
fcx.write_ty(pat.id, pat_ty);
554+
fcx.write_substs(pat.id, ty::ItemSubsts { substs: item_substs });
585555
}
586556

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

0 commit comments

Comments
 (0)