diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 072966abf2c40..91848abd68d36 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -393,6 +393,48 @@ $EndFeature, "
             }
         }
 
+        doc_comment! {
+            concat!("Returns the number of leading ones in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "#![feature(leading_trailing_ones)]
+let n = -1", stringify!($SelfT), ";
+
+assert_eq!(n.leading_ones(), ", stringify!($BITS), ");",
+$EndFeature, "
+```"),
+            #[unstable(feature = "leading_trailing_ones", issue = "57969")]
+            #[inline]
+            pub const fn leading_ones(self) -> u32 {
+                (self as $UnsignedT).leading_ones()
+            }
+        }
+
+        doc_comment! {
+            concat!("Returns the number of trailing ones in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "#![feature(leading_trailing_ones)]
+let n = 3", stringify!($SelfT), ";
+
+assert_eq!(n.trailing_ones(), 2);",
+$EndFeature, "
+```"),
+            #[unstable(feature = "leading_trailing_ones", issue = "57969")]
+            #[inline]
+            pub const fn trailing_ones(self) -> u32 {
+                (self as $UnsignedT).trailing_ones()
+            }
+        }
+
         doc_comment! {
             concat!("Shifts the bits to the left by a specified amount, `n`,
 wrapping the truncated bits to the end of the resulting integer.
@@ -2485,6 +2527,47 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
             }
         }
 
+        doc_comment! {
+            concat!("Returns the number of leading ones in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "#![feature(leading_trailing_ones)]
+let n = !(", stringify!($SelfT), "::max_value() >> 2);
+
+assert_eq!(n.leading_ones(), 2);", $EndFeature, "
+```"),
+            #[unstable(feature = "leading_trailing_ones", issue = "57969")]
+            #[inline]
+            pub const fn leading_ones(self) -> u32 {
+                (!self).leading_zeros()
+            }
+        }
+
+        doc_comment! {
+            concat!("Returns the number of trailing ones in the binary representation
+of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "#![feature(leading_trailing_ones)]
+let n = 0b1010111", stringify!($SelfT), ";
+
+assert_eq!(n.trailing_ones(), 3);", $EndFeature, "
+```"),
+            #[unstable(feature = "leading_trailing_ones", issue = "57969")]
+            #[inline]
+            pub const fn trailing_ones(self) -> u32 {
+                (!self).trailing_zeros()
+            }
+        }
+
         doc_comment! {
             concat!("Shifts the bits to the left by a specified amount, `n`,
 wrapping the truncated bits to the end of the resulting integer.
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 86cf6fc104c83..36476cf01c08c 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -41,6 +41,7 @@
 #![feature(const_raw_ptr_deref)]
 #![feature(never_type)]
 #![feature(unwrap_infallible)]
+#![feature(leading_trailing_ones)]
 
 extern crate test;
 
diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs
index 4a44b5f24b910..48a49073b2cf5 100644
--- a/src/libcore/tests/num/int_macros.rs
+++ b/src/libcore/tests/num/int_macros.rs
@@ -89,6 +89,33 @@ macro_rules! int_module {
                 assert_eq!(C.count_zeros(), bits as u32 - 5);
             }
 
+            #[test]
+            fn test_leading_trailing_ones() {
+                let bits = (mem::size_of::<$T>() * 8) as u32;
+
+                let a: $T = 0b0101_1111;
+                assert_eq!(a.trailing_ones(), 5);
+                assert_eq!((!a).leading_ones(), bits - 7);
+
+                assert_eq!(a.reverse_bits().leading_ones(), 5);
+
+                assert_eq!(_1.leading_ones(), bits);
+                assert_eq!(_1.trailing_ones(), bits);
+
+                assert_eq!((_1 << 1).trailing_ones(), 0);
+                assert_eq!(MAX.leading_ones(), 0);
+
+                assert_eq!((_1 << 1).leading_ones(), bits - 1);
+                assert_eq!(MAX.trailing_ones(), bits - 1);
+
+                assert_eq!(_0.leading_ones(), 0);
+                assert_eq!(_0.trailing_ones(), 0);
+
+                let x: $T = 0b0010_1100;
+                assert_eq!(x.leading_ones(), 0);
+                assert_eq!(x.trailing_ones(), 0);
+            }
+
             #[test]
             fn test_rotate() {
                 assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
diff --git a/src/libcore/tests/num/uint_macros.rs b/src/libcore/tests/num/uint_macros.rs
index f94b2f56bbbec..8f1ca8e6fac2c 100644
--- a/src/libcore/tests/num/uint_macros.rs
+++ b/src/libcore/tests/num/uint_macros.rs
@@ -53,6 +53,33 @@ macro_rules! uint_module {
                 assert!(C.count_zeros() == bits as u32 - 5);
             }
 
+            #[test]
+            fn test_leading_trailing_ones() {
+                let bits = (mem::size_of::<$T>() * 8) as u32;
+
+                let a: $T = 0b0101_1111;
+                assert_eq!(a.trailing_ones(), 5);
+                assert_eq!((!a).leading_ones(), bits - 7);
+
+                assert_eq!(a.reverse_bits().leading_ones(), 5);
+
+                assert_eq!(_1.leading_ones(), bits);
+                assert_eq!(_1.trailing_ones(), bits);
+
+                assert_eq!((_1 << 1).trailing_ones(), 0);
+                assert_eq!((_1 >> 1).leading_ones(), 0);
+
+                assert_eq!((_1 << 1).leading_ones(), bits - 1);
+                assert_eq!((_1 >> 1).trailing_ones(), bits - 1);
+
+                assert_eq!(_0.leading_ones(), 0);
+                assert_eq!(_0.trailing_ones(), 0);
+
+                let x: $T = 0b0010_1100;
+                assert_eq!(x.leading_ones(), 0);
+                assert_eq!(x.trailing_ones(), 0);
+            }
+
             #[test]
             fn test_rotate() {
                 assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);