mir: Get the right non-reference type for binding patterns.

This commit is contained in:
Eduard Burtescu 2016-03-09 23:32:52 +02:00
parent cf4daf7889
commit aca4f9396d
3 changed files with 15 additions and 21 deletions

View File

@ -488,7 +488,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
.map(|subpattern| {
// e.g., `(x as Variant).0`
let lvalue = downcast_lvalue.clone().field(subpattern.field,
subpattern.field_ty());
subpattern.pattern.ty);
// e.g., `(x as Variant).0 @ P1`
MatchPair::new(lvalue, &subpattern.pattern)
});

View File

@ -22,7 +22,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
subpatterns.iter()
.map(|fieldpat| {
let lvalue = lvalue.clone().field(fieldpat.field,
fieldpat.field_ty());
fieldpat.pattern.ty);
MatchPair::new(lvalue, &fieldpat.pattern)
})
.collect()

View File

@ -63,6 +63,8 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
}
fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
let mut ty = self.cx.tcx.node_id_to_type(pat.id);
let kind = match pat.node {
PatKind::Wild => PatternKind::Wild,
@ -169,6 +171,17 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
hir::BindByRef(hir::MutImmutable) =>
(Mutability::Not, BindingMode::ByRef(region.unwrap(), BorrowKind::Shared)),
};
// A ref x pattern is the same node used for x, and as such it has
// x's type, which is &T, where we want T (the type being matched).
if let hir::BindByRef(_) = bm {
if let ty::TyRef(_, mt) = ty.sty {
ty = mt.ty;
} else {
unreachable!("`ref {}` has wrong type {}", ident.node, ty);
}
}
PatternKind::Binding {
mutability: mutability,
mode: mode,
@ -234,8 +247,6 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
}
};
let ty = self.cx.tcx.node_id_to_type(pat.id);
Pattern {
span: pat.span,
ty: ty,
@ -314,20 +325,3 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
}
}
}
impl<'tcx> FieldPattern<'tcx> {
pub fn field_ty(&self) -> Ty<'tcx> {
debug!("field_ty({:?},ty={:?})", self, self.pattern.ty);
let r = match *self.pattern.kind {
PatternKind::Binding { mode: BindingMode::ByRef(..), ..} => {
match self.pattern.ty.sty {
ty::TyRef(_, mt) => mt.ty,
_ => unreachable!()
}
}
_ => self.pattern.ty
};
debug!("field_ty -> {:?}", r);
r
}
}