about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-03-09 23:32:52 +0200
committerEduard Burtescu <edy.burt@gmail.com>2016-03-17 21:51:55 +0200
commitaca4f9396d58bd9966f48fcf7b71a093264ed272 (patch)
treef78c3166da01f9f99f95b448e0f4a44ea45c70b0
parentcf4daf7889706d618a66d5c10332764a0793f05e (diff)
downloadrust-aca4f9396d58bd9966f48fcf7b71a093264ed272.tar.gz
rust-aca4f9396d58bd9966f48fcf7b71a093264ed272.zip
mir: Get the right non-reference type for binding patterns.
-rw-r--r--src/librustc_mir/build/matches/test.rs2
-rw-r--r--src/librustc_mir/build/matches/util.rs2
-rw-r--r--src/librustc_mir/hair/cx/pattern.rs32
3 files changed, 15 insertions, 21 deletions
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 113084f8ccd..0efa24f3119 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -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)
                        });
diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs
index d9b90fff784..b46c3ffb76a 100644
--- a/src/librustc_mir/build/matches/util.rs
+++ b/src/librustc_mir/build/matches/util.rs
@@ -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()
diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs
index d1e3f08aff8..232404417e0 100644
--- a/src/librustc_mir/hair/cx/pattern.rs
+++ b/src/librustc_mir/hair/cx/pattern.rs
@@ -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
-    }
-}