diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 9f9dbd0777a14..2b6c376f8a71c 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -146,7 +146,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use iter::{FromIterator, FusedIterator, TrustedLen};
-use {hint, mem, ops};
+use {hint, mem, ops::{self, Deref}};
 use mem::PinMut;
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
@@ -953,6 +953,17 @@ impl<T: Default> Option<T> {
     }
 }
 
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T: Deref> Option<T> {
+    /// Converts from `&Option<T>` to `Option<&T::Target>`.
+    ///
+    /// Leaves the original Option in-place, creating a new one with a reference
+    /// to the original one, additionally coercing the contents via `Deref`.
+    pub fn deref(&self) -> Option<&T::Target> {
+        self.as_ref().map(|t| t.deref())
+    }
+}
+
 impl<T, E> Option<Result<T, E>> {
     /// Transposes an `Option` of a `Result` into a `Result` of an `Option`.
     ///
@@ -989,7 +1000,6 @@ fn expect_failed(msg: &str) -> ! {
     panic!("{}", msg)
 }
 
-
 /////////////////////////////////////////////////////////////////////////////
 // Trait implementations
 /////////////////////////////////////////////////////////////////////////////
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index e0cc669d0350a..fb496836c2c10 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -242,7 +242,7 @@
 
 use fmt;
 use iter::{FromIterator, FusedIterator, TrustedLen};
-use ops;
+use ops::{self, Deref};
 
 /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).
 ///
@@ -909,6 +909,44 @@ impl<T: Default, E> Result<T, E> {
     }
 }
 
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T: Deref, E> Result<T, E> {
+    /// Converts from `&Result<T, E>` to `Result<&T::Target, &E>`.
+    ///
+    /// Leaves the original Result in-place, creating a new one with a reference
+    /// to the original one, additionally coercing the `Ok` arm of the Result via
+    /// `Deref`.
+    pub fn deref_ok(&self) -> Result<&T::Target, &E> {
+        self.as_ref().map(|t| t.deref())
+    }
+}
+
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T, E: Deref> Result<T, E> {
+    /// Converts from `&Result<T, E>` to `Result<&T, &E::Target>`.
+    ///
+    /// Leaves the original Result in-place, creating a new one with a reference
+    /// to the original one, additionally coercing the `Err` arm of the Result via
+    /// `Deref`.
+    pub fn deref_err(&self) -> Result<&T, &E::Target>
+    {
+        self.as_ref().map_err(|e| e.deref())
+    }
+}
+
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T: Deref, E: Deref> Result<T, E> {
+    /// Converts from `&Result<T, E>` to `Result<&T::Target, &E::Target>`.
+    ///
+    /// Leaves the original Result in-place, creating a new one with a reference
+    /// to the original one, additionally coercing both the `Ok` and `Err` arms
+    /// of the Result via `Deref`.
+    pub fn deref(&self) -> Result<&T::Target, &E::Target>
+    {
+        self.as_ref().map(|t| t.deref()).map_err(|e| e.deref())
+    }
+}
+
 impl<T, E> Result<Option<T>, E> {
     /// Transposes a `Result` of an `Option` into an `Option` of a `Result`.
     ///
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 6fcfaae453500..2323b30a0104a 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -43,6 +43,7 @@
 #![feature(align_offset)]
 #![feature(reverse_bits)]
 #![feature(iterator_find_map)]
+#![feature(inner_deref)]
 #![feature(slice_internals)]
 #![feature(option_replace)]
 
diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs
index 324ebf435651d..1324ba2d9a9c3 100644
--- a/src/libcore/tests/option.rs
+++ b/src/libcore/tests/option.rs
@@ -298,6 +298,23 @@ fn test_try() {
     assert_eq!(try_option_err(), Err(NoneError));
 }
 
+#[test]
+fn test_option_deref() {
+    // Some: &Option<T: Deref>::Some(T) -> Option<&T::Deref::Target>::Some(&*T)
+    let ref_option = &Some(&42);
+    assert_eq!(ref_option.deref(), Some(&42));
+
+    let ref_option = &Some(String::from("a result"));
+    assert_eq!(ref_option.deref(), Some("a result"));
+
+    let ref_option = &Some(vec![1, 2, 3, 4, 5]);
+    assert_eq!(ref_option.deref(), Some(&[1, 2, 3, 4, 5][..]));
+
+    // None: &Option<T: Deref>>::None -> None
+    let ref_option: &Option<&i32> = &None;
+    assert_eq!(ref_option.deref(), None);
+}
+
 #[test]
 fn test_replace() {
     let mut x = Some(2);
diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs
index 0616252c82c89..0c00992ffd84e 100644
--- a/src/libcore/tests/result.rs
+++ b/src/libcore/tests/result.rs
@@ -233,3 +233,96 @@ fn test_try() {
     }
     assert_eq!(try_result_err(), Err(1));
 }
+
+#[test]
+fn test_result_deref() {
+    // &Result<T: Deref, E>::Ok(T).deref_ok() ->
+    //      Result<&T::Deref::Target, &E>::Ok(&*T)
+    let ref_ok = &Result::Ok::<&i32, u8>(&42);
+    let expected_result = Result::Ok::<&i32, &u8>(&42);
+    assert_eq!(ref_ok.deref_ok(), expected_result);
+
+    let ref_ok = &Result::Ok::<String, u32>(String::from("a result"));
+    let expected_result = Result::Ok::<&str, &u32>("a result");
+    assert_eq!(ref_ok.deref_ok(), expected_result);
+
+    let ref_ok = &Result::Ok::<Vec<i32>, u32>(vec![1, 2, 3, 4, 5]);
+    let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]);
+    assert_eq!(ref_ok.deref_ok(), expected_result);
+
+    // &Result<T: Deref, E: Deref>::Ok(T).deref() ->
+    //      Result<&T::Deref::Target, &E::Deref::Target>::Ok(&*T)
+    let ref_ok = &Result::Ok::<&i32, &u8>(&42);
+    let expected_result = Result::Ok::<&i32, &u8>(&42);
+    assert_eq!(ref_ok.deref(), expected_result);
+
+    let ref_ok = &Result::Ok::<String, &u32>(String::from("a result"));
+    let expected_result = Result::Ok::<&str, &u32>("a result");
+    assert_eq!(ref_ok.deref(), expected_result);
+
+    let ref_ok = &Result::Ok::<Vec<i32>, &u32>(vec![1, 2, 3, 4, 5]);
+    let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]);
+    assert_eq!(ref_ok.deref(), expected_result);
+
+    // &Result<T, E: Deref>::Err(T).deref_err() ->
+    //      Result<&T, &E::Deref::Target>::Err(&*E)
+    let ref_err = &Result::Err::<u8, &i32>(&41);
+    let expected_result = Result::Err::<&u8, &i32>(&41);
+    assert_eq!(ref_err.deref_err(), expected_result);
+
+    let ref_err = &Result::Err::<u32, String>(String::from("an error"));
+    let expected_result = Result::Err::<&u32, &str>("an error");
+    assert_eq!(ref_err.deref_err(), expected_result);
+
+    let ref_err = &Result::Err::<u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
+    let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]);
+    assert_eq!(ref_err.deref_err(), expected_result);
+
+    // &Result<T: Deref, E: Deref>::Err(T).deref_err() ->
+    //      Result<&T, &E::Deref::Target>::Err(&*E)
+    let ref_err = &Result::Err::<&u8, &i32>(&41);
+    let expected_result = Result::Err::<&u8, &i32>(&41);
+    assert_eq!(ref_err.deref(), expected_result);
+
+    let ref_err = &Result::Err::<&u32, String>(String::from("an error"));
+    let expected_result = Result::Err::<&u32, &str>("an error");
+    assert_eq!(ref_err.deref(), expected_result);
+
+    let ref_err = &Result::Err::<&u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
+    let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]);
+    assert_eq!(ref_err.deref(), expected_result);
+
+    // The following cases test calling deref_* with the wrong variant (i.e.
+    // `deref_ok()` with a `Result::Err()`, or `deref_err()` with a `Result::Ok()`.
+    // While unusual, these cases are supported to ensure that an `inner_deref`
+    // call can still be made even when one of the Result types does not implement
+    // `Deref` (for example, std::io::Error).
+
+    // &Result<T, E: Deref>::Ok(T).deref_err() ->
+    //      Result<&T, &E::Deref::Target>::Ok(&T)
+    let ref_ok = &Result::Ok::<i32, &u8>(42);
+    let expected_result = Result::Ok::<&i32, &u8>(&42);
+    assert_eq!(ref_ok.deref_err(), expected_result);
+
+    let ref_ok = &Result::Ok::<&str, &u32>("a result");
+    let expected_result = Result::Ok::<&&str, &u32>(&"a result");
+    assert_eq!(ref_ok.deref_err(), expected_result);
+
+    let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]);
+    let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]);
+    assert_eq!(ref_ok.deref_err(), expected_result);
+
+    // &Result<T: Deref, E>::Err(E).deref_ok() ->
+    //      Result<&T::Deref::Target, &E>::Err(&E)
+    let ref_err = &Result::Err::<&u8, i32>(41);
+    let expected_result = Result::Err::<&u8, &i32>(&41);
+    assert_eq!(ref_err.deref_ok(), expected_result);
+
+    let ref_err = &Result::Err::<&u32, &str>("an error");
+    let expected_result = Result::Err::<&u32, &&str>(&"an error");
+    assert_eq!(ref_err.deref_ok(), expected_result);
+
+    let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]);
+    let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]);
+    assert_eq!(ref_err.deref_ok(), expected_result);
+}
diff --git a/src/test/compile-fail/issue-50264-inner-deref-trait/option_deref.rs b/src/test/compile-fail/issue-50264-inner-deref-trait/option_deref.rs
new file mode 100644
index 0000000000000..4c67fb3bef103
--- /dev/null
+++ b/src/test/compile-fail/issue-50264-inner-deref-trait/option_deref.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &Some(42).deref();
+//~^ ERROR no method named `deref` found for type `std::option::Option<{integer}>`
+}
diff --git a/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref.rs b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref.rs
new file mode 100644
index 0000000000000..73bdf0b920907
--- /dev/null
+++ b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &Ok(42).deref();
+//~^ ERROR no method named `deref` found
+}
diff --git a/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_err.rs b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_err.rs
new file mode 100644
index 0000000000000..5d1e7472d8f18
--- /dev/null
+++ b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_err.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &Err(41).deref_err();
+//~^ ERROR no method named `deref_err` found
+}
diff --git a/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_ok.rs b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_ok.rs
new file mode 100644
index 0000000000000..bee8e0c062bae
--- /dev/null
+++ b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_ok.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &Ok(42).deref_ok();
+//~^ ERROR no method named `deref_ok` found
+}