]> git.lizzy.rs Git - rust.git/commitdiff
extract autoderef type adjustment code into a reusable
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 18 Aug 2015 21:57:42 +0000 (17:57 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Sun, 6 Sep 2015 11:27:22 +0000 (07:27 -0400)
helper

src/librustc/middle/ty.rs

index 2e17a063775c6263512e3482a7e1b3a542764e4f..98422d1dffe5e28a99c4dcc5c2477073056d47c6 100644 (file)
@@ -5191,28 +5191,12 @@ pub fn adjust<F>(&'tcx self, cx: &ctxt<'tcx>,
 
                         if !adjusted_ty.references_error() {
                             for i in 0..adj.autoderefs {
-                                let method_call = MethodCall::autoderef(expr_id, i as u32);
-                                match method_type(method_call) {
-                                    Some(method_ty) => {
-                                        // Overloaded deref operators have all late-bound
-                                        // regions fully instantiated and coverge.
-                                        let fn_ret =
-                                            cx.no_late_bound_regions(&method_ty.fn_ret()).unwrap();
-                                        adjusted_ty = fn_ret.unwrap();
-                                    }
-                                    None => {}
-                                }
-                                match adjusted_ty.builtin_deref(true, NoPreference) {
-                                    Some(mt) => { adjusted_ty = mt.ty; }
-                                    None => {
-                                        cx.sess.span_bug(
-                                            span,
-                                            &format!("the {}th autoderef failed: {}",
-                                                    i,
-                                                     adjusted_ty)
-                                            );
-                                    }
-                                }
+                                adjusted_ty =
+                                    adjusted_ty.adjust_for_autoderef(cx,
+                                                                     expr_id,
+                                                                     span,
+                                                                     i as u32,
+                                                                     &mut method_type);
                             }
                         }
 
@@ -5228,6 +5212,39 @@ pub fn adjust<F>(&'tcx self, cx: &ctxt<'tcx>,
         };
     }
 
+    pub fn adjust_for_autoderef<F>(&'tcx self,
+                                   cx: &ctxt<'tcx>,
+                                   expr_id: ast::NodeId,
+                                   expr_span: Span,
+                                   autoderef: u32, // how many autoderefs so far?
+                                   mut method_type: F)
+                                   -> Ty<'tcx> where
+        F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
+    {
+        let method_call = MethodCall::autoderef(expr_id, autoderef);
+        let mut adjusted_ty = self;
+        match method_type(method_call) {
+            Some(method_ty) => {
+                // Method calls always have all late-bound regions
+                // fully instantiated.
+                let fn_ret = cx.no_late_bound_regions(&method_ty.fn_ret()).unwrap();
+                adjusted_ty = fn_ret.unwrap();
+            }
+            None => {}
+        }
+        match adjusted_ty.builtin_deref(true, NoPreference) {
+            Some(mt) => mt.ty,
+            None => {
+                cx.sess.span_bug(
+                    expr_span,
+                    &format!("the {}th autoderef failed: {}",
+                             autoderef,
+                             adjusted_ty)
+                        );
+            }
+        }
+    }
+
     pub fn adjust_for_autoref(&'tcx self, cx: &ctxt<'tcx>,
                               autoref: Option<AutoRef<'tcx>>)
                               -> Ty<'tcx> {