]> git.lizzy.rs Git - rust.git/commitdiff
mir: Get the right non-reference type for binding patterns.
authorEduard Burtescu <edy.burt@gmail.com>
Wed, 9 Mar 2016 21:32:52 +0000 (23:32 +0200)
committerEduard Burtescu <edy.burt@gmail.com>
Thu, 17 Mar 2016 19:51:55 +0000 (21:51 +0200)
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/matches/util.rs
src/librustc_mir/hair/cx/pattern.rs

index 113084f8ccd22dcedfb6c0a6ad9a43d877b97896..0efa24f3119432af582b4003f374a42d5fa14e9a 100644 (file)
@@ -488,7 +488,7 @@ fn candidate_after_variant_switch<'pat>(&mut self,
                        .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)
                        });
index d9b90fff78446694c3e112108c3c9f0a76062592..b46c3ffb76a1b82dab822db1771059eb88f14089 100644 (file)
@@ -22,7 +22,7 @@ pub fn field_match_pairs<'pat>(&mut self,
         subpatterns.iter()
                    .map(|fieldpat| {
                        let lvalue = lvalue.clone().field(fieldpat.field,
-                                                         fieldpat.field_ty());
+                                                         fieldpat.pattern.ty);
                        MatchPair::new(lvalue, &fieldpat.pattern)
                    })
                    .collect()
index d1e3f08aff894d01ea538f23b4e943bfba94bace..232404417e0e4f605709a3f5e06015f4c6739e17 100644 (file)
@@ -63,6 +63,8 @@ fn new(cx: &'patcx mut Cx<'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 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'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 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
             }
         };
 
-        let ty = self.cx.tcx.node_id_to_type(pat.id);
-
         Pattern {
             span: pat.span,
             ty: ty,
@@ -314,20 +325,3 @@ fn variant_or_leaf(&mut self,
         }
     }
 }
-
-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
-    }
-}