about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-08-18 17:57:42 -0400
committerNiko Matsakis <niko@alum.mit.edu>2015-09-06 07:27:22 -0400
commit0e764ec5ce24be6d6306188673b05f8d9b4f81e5 (patch)
tree20af8dddf1652d6fdc05b252b9511cf390636532
parent714f2a8921b1e686ae2ba02965fcd3b3e733e4c3 (diff)
extract autoderef type adjustment code into a reusable
helper
-rw-r--r--src/librustc/middle/ty.rs61
1 files changed, 39 insertions, 22 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 2e17a063775..98422d1dffe 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -5191,28 +5191,12 @@ impl<'tcx> TyS<'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 @@ impl<'tcx> TyS<'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> {