]> git.lizzy.rs Git - rust.git/commitdiff
break type-checking of aggregate-kind out into helper function
authorNiko Matsakis <niko@alum.mit.edu>
Fri, 17 Nov 2017 18:28:01 +0000 (13:28 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Mon, 4 Dec 2017 13:51:13 +0000 (08:51 -0500)
src/librustc_mir/transform/type_check.rs

index 3b41b2545bf5597714751f3cec4aacb4f2c59308..fc2a51e27381922865cb756ecfda5d236149f7e3 100644 (file)
@@ -1031,13 +1031,13 @@ fn check_local(&mut self, mir: &Mir<'tcx>, local: Local, local_decl: &LocalDecl<
 
     fn aggregate_field_ty(
         &mut self,
-        ak: &Box<AggregateKind<'tcx>>,
+        ak: &AggregateKind<'tcx>,
         field_index: usize,
         location: Location,
     ) -> Result<Ty<'tcx>, FieldAccessError> {
         let tcx = self.tcx();
 
-        match **ak {
+        match *ak {
             AggregateKind::Adt(def, variant_index, substs, active_field_index) => {
                 let variant = &def.variants[variant_index];
                 let adj_field_index = active_field_index.unwrap_or(field_index);
@@ -1069,56 +1069,17 @@ fn aggregate_field_ty(
                     }
                 }
             }
-            AggregateKind::Array(ty) => {
-                Ok(ty)
-            }
+            AggregateKind::Array(ty) => Ok(ty),
             AggregateKind::Tuple => {
                 unreachable!("This should have been covered in check_rvalues");
             }
         }
     }
 
-    fn check_rvalue(&mut self, mir: &Mir<'tcx>, rv: &Rvalue<'tcx>, location: Location) {
-        let tcx = self.tcx();
-        match rv {
+    fn check_rvalue(&mut self, mir: &Mir<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
+        match rvalue {
             Rvalue::Aggregate(ak, ops) => {
-                match **ak {
-                    // tuple rvalue field type is always the type of the op. Nothing to check here.
-                    AggregateKind::Tuple => {}
-                    _ => {
-                        for (i, op) in ops.iter().enumerate() {
-                            let field_ty = match self.aggregate_field_ty(ak, i, location) {
-                                Ok(field_ty) => field_ty,
-                                Err(FieldAccessError::OutOfRange { field_count }) => {
-                                    span_mirbug!(
-                                        self,
-                                        rv,
-                                        "accessed field #{} but variant only has {}",
-                                        i,
-                                        field_count
-                                    );
-                                    continue;
-                                }
-                            };
-                            let op_ty = op.ty(mir, tcx);
-                            if let Err(terr) = self.sub_types(
-                                op_ty,
-                                field_ty,
-                                location.at_successor_within_block(),
-                            )
-                                {
-                                    span_mirbug!(
-                                    self,
-                                    rv,
-                                    "{:?} is not a subtype of {:?}: {:?}",
-                                    op_ty,
-                                    field_ty,
-                                    terr
-                                );
-                                }
-                        }
-                    }
-                }
+                self.check_aggregate_rvalue(mir, rvalue, ak, ops, location)
             }
             // FIXME: These other cases have to be implemented in future PRs
             Rvalue::Use(..) |
@@ -1134,6 +1095,52 @@ fn check_rvalue(&mut self, mir: &Mir<'tcx>, rv: &Rvalue<'tcx>, location: Locatio
         }
     }
 
+    fn check_aggregate_rvalue(
+        &mut self,
+        mir: &Mir<'tcx>,
+        rvalue: &Rvalue<'tcx>,
+        aggregate_kind: &AggregateKind<'tcx>,
+        operands: &[Operand<'tcx>],
+        location: Location,
+    ) {
+        match aggregate_kind {
+            // tuple rvalue field type is always the type of the op. Nothing to check here.
+            AggregateKind::Tuple => return,
+            _ => {}
+        }
+
+        let tcx = self.tcx();
+
+        for (i, operand) in operands.iter().enumerate() {
+            let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
+                Ok(field_ty) => field_ty,
+                Err(FieldAccessError::OutOfRange { field_count }) => {
+                    span_mirbug!(
+                        self,
+                        rvalue,
+                        "accessed field #{} but variant only has {}",
+                        i,
+                        field_count
+                    );
+                    continue;
+                }
+            };
+            let operand_ty = operand.ty(mir, tcx);
+            if let Err(terr) =
+                self.sub_types(operand_ty, field_ty, location.at_successor_within_block())
+            {
+                span_mirbug!(
+                    self,
+                    rvalue,
+                    "{:?} is not a subtype of {:?}: {:?}",
+                    operand_ty,
+                    field_ty,
+                    terr
+                );
+            }
+        }
+    }
+
     fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
         self.last_span = mir.span;
         debug!("run_on_mir: {:?}", mir.span);