diff --git a/Cargo.toml b/Cargo.toml
index a9f0f59603b01b131042683331077513ff9d441f..9427da76cf27837c763e40f6cc13dc911d75d937 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,7 @@ description = """
 A library for types and bindings to native C functions often found in libc or
 other common platform libraries.
 """
+build = "build.rs"
 
 [badges]
 travis-ci = { repository = "rust-lang/libc" }
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000000000000000000000000000000000000..aa56ea054506c4f0947ec8aac5a20d62723b8e1a
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,35 @@
+use std::env;
+use std::process::Command;
+use std::str;
+
+fn main() {
+    /*
+     * If `core::ffi::c_void` exists, libc can just re-export it. Otherwise, it
+     * must define an incompatible type to retain backwards-compatibility.
+     */
+    if rustc_minor_version().expect("Failed to get rustc version") >= 31 {
+        println!("cargo:rustc-cfg=core_cvoid");
+    }
+}
+
+fn rustc_minor_version() -> Option<u32> {
+    macro_rules! otry {
+        ($e:expr) => {
+            match $e {
+                Some(e) => e,
+                None => return None,
+            }
+        };
+    }
+
+    let rustc = otry!(env::var_os("RUSTC"));
+    let output = otry!(Command::new(rustc).arg("--version").output().ok());
+    let version = otry!(str::from_utf8(&output.stdout).ok());
+    let mut pieces = version.split('.');
+
+    if pieces.next() != Some("rustc 1") {
+        return None;
+    }
+
+    otry!(pieces.next()).parse().ok()
+}
diff --git a/src/lib.rs b/src/lib.rs
index 7f8e907aaf7b15088bfe7132993122006d5e32a1..823d36c19c160f4919dd28118a0463a6ffa925fc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -108,17 +108,22 @@ cfg_if! {
         // On the Switch, we only define some useful universal types for
         // convenience. Those can be found in the switch.rs file.
     } else {
-
-        // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
-        // more optimization opportunities around it recognizing things like
-        // malloc/free.
-        #[repr(u8)]
-        pub enum c_void {
-            // Two dummy variants so the #[repr] attribute can be used.
-            #[doc(hidden)]
-            __variant1,
-            #[doc(hidden)]
-            __variant2,
+        cfg_if! {
+            if #[cfg(core_cvoid)] {
+                pub use core::ffi::c_void;
+            } else {
+                // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
+                // more optimization opportunities around it recognizing things like
+                // malloc/free.
+                #[repr(u8)]
+                pub enum c_void {
+                    // Two dummy variants so the #[repr] attribute can be used.
+                    #[doc(hidden)]
+                    __variant1,
+                    #[doc(hidden)]
+                    __variant2,
+                }
+            }
         }
 
         pub type int8_t = i8;
diff --git a/src/switch.rs b/src/switch.rs
index c11379541ea08f95a912f6f5672bf33e344c9228..bb6df388e1564f414c10555511f6522046d043a3 100644
--- a/src/switch.rs
+++ b/src/switch.rs
@@ -1,17 +1,5 @@
 //! Switch C type definitions
 
-// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
-// more optimization opportunities around it recognizing things like
-// malloc/free.
-#[repr(u8)]
-pub enum c_void {
-    // Two dummy variants so the #[repr] attribute can be used.
-    #[doc(hidden)]
-    __variant1,
-    #[doc(hidden)]
-    __variant2,
-}
-
 pub type int8_t = i8;
 pub type int16_t = i16;
 pub type int32_t = i32;
@@ -46,3 +34,21 @@ pub type c_char = u8;
 pub type c_long = i64;
 pub type c_ulong = u64;
 pub type wchar_t = u32;
+
+cfg_if! {
+    if #[cfg(core_cvoid)] {
+        pub use core::ffi::c_void;
+    } else {
+        // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help
+        // enable more optimization opportunities around it recognizing things
+        // like malloc/free.
+        #[repr(u8)]
+        pub enum c_void {
+            // Two dummy variants so the #[repr] attribute can be used.
+            #[doc(hidden)]
+            __variant1,
+            #[doc(hidden)]
+            __variant2,
+        }
+    }
+}