diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 267ac8b2f4d..b75b06f42b6 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -505,10 +505,7 @@ impl get_node_info for ast::Block {
 
 impl get_node_info for Option<@ast::Expr> {
     fn info(&self) -> Option<NodeInfo> {
-        match *self {
-            Some(ref s) => s.info(),
-            None => None,
-        }
+        self.and_then_ref(|s| s.info())
     }
 }
 
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index f942638a8ad..36405136e63 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -745,17 +745,10 @@ pub fn ty_of_closure<AC:AstConv,RS:RegionScope + Clone + 'static>(
                           RegionParamNames(bound_lifetime_names.clone()));
 
     let input_tys = do decl.inputs.iter().enumerate().map |(i, a)| {
-        let expected_arg_ty = match expected_sig {
-            Some(ref e) => {
-                // no guarantee that the correct number of expected args
-                // were supplied
-                if i < e.inputs.len() {
-                    Some(e.inputs[i])
-                } else {
-                    None
-                }
-            }
-            None => None,
+        let expected_arg_ty = do expected_sig.and_then_ref |e| {
+            // no guarantee that the correct number of expected args
+            // were supplied
+            if i < e.inputs.len() {Some(e.inputs[i])} else {None}
         };
         ty_of_arg(this, &rb, a, expected_arg_ty)
     }.collect();
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs
index f36fb2d98bd..ec3c02a31f2 100644
--- a/src/libstd/iter.rs
+++ b/src/libstd/iter.rs
@@ -1504,12 +1504,7 @@ impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'self,
                 }
             }
             match self.iter.next().map_move(|x| (self.f)(x)) {
-                None => {
-                    return match self.backiter {
-                        Some(ref mut it) => it.next(),
-                        None => None,
-                    };
-                }
+                None => return self.backiter.and_then_mut_ref(|it| it.next()),
                 next => self.frontiter = next,
             }
         }
@@ -1541,12 +1536,7 @@ impl<'self,
                 }
             }
             match self.iter.next_back().map_move(|x| (self.f)(x)) {
-                None => {
-                    return match self.frontiter {
-                        Some(ref mut it) => it.next_back(),
-                        None => None,
-                    };
-                }
+                None => return self.frontiter.and_then_mut_ref(|it| it.next_back()),
                 next => self.backiter = next,
             }
         }
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index 968330a18a8..ce725257dff 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -138,8 +138,8 @@ impl<T> Option<T> {
         }
     }
 
-    /// Returns `None` if the option is `None`, otherwise calls and returns the
-    /// value of `f`.
+    /// Returns `None` if the option is `None`, otherwise calls `f` with the
+    /// wrapped value and returns the result.
     #[inline]
     pub fn and_then<U>(self, f: &fn(T) -> Option<U>) -> Option<U> {
         match self {
@@ -148,6 +148,26 @@ impl<T> Option<T> {
         }
     }
 
+    /// Returns `None` if the option is `None`, otherwise calls `f` with a
+    /// reference to the wrapped value and returns the result.
+    #[inline]
+    pub fn and_then_ref<'a, U>(&'a self, f: &fn(&'a T) -> Option<U>) -> Option<U> {
+        match *self {
+            Some(ref x) => f(x),
+            None => None
+        }
+    }
+
+    /// Returns `None` if the option is `None`, otherwise calls `f` with a
+    /// mutable reference to the wrapped value and returns the result.
+    #[inline]
+    pub fn and_then_mut_ref<'a, U>(&'a mut self, f: &fn(&'a mut T) -> Option<U>) -> Option<U> {
+        match *self {
+            Some(ref mut x) => f(x),
+            None => None
+        }
+    }
+
     /// Returns the option if it contains a value, otherwise returns `optb`.
     #[inline]
     pub fn or(self, optb: Option<T>) -> Option<T> {
@@ -157,8 +177,8 @@ impl<T> Option<T> {
         }
     }
 
-    /// Returns the option if it contains a value, otherwise calls and returns the
-    /// value of `f`.
+    /// Returns the option if it contains a value, otherwise calls `f` and
+    /// returns the result.
     #[inline]
     pub fn or_else(self, f: &fn() -> Option<T>) -> Option<T> {
         match self {