diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 8ab07e9e5b564..f8b3ee0edc8ee 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -663,6 +663,7 @@ pub fn distcheck(build: &Build) {
         return
     }
 
+    println!("Distcheck");
     let dir = build.out.join("tmp").join("distcheck");
     let _ = fs::remove_dir_all(&dir);
     t!(fs::create_dir_all(&dir));
@@ -680,6 +681,26 @@ pub fn distcheck(build: &Build) {
     build.run(Command::new(build_helper::make(&build.config.build))
                      .arg("check")
                      .current_dir(&dir));
+
+    // Now make sure that rust-src has all of libstd's dependencies
+    println!("Distcheck rust-src");
+    let dir = build.out.join("tmp").join("distcheck-src");
+    let _ = fs::remove_dir_all(&dir);
+    t!(fs::create_dir_all(&dir));
+
+    let mut cmd = Command::new("tar");
+    cmd.arg("-xzf")
+       .arg(dist::rust_src_installer(build))
+       .arg("--strip-components=1")
+       .current_dir(&dir);
+    build.run(&mut cmd);
+
+    let toml = dir.join("rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml");
+    build.run(Command::new(&build.cargo)
+                     .arg("generate-lockfile")
+                     .arg("--manifest-path")
+                     .arg(&toml)
+                     .current_dir(&dir));
 }
 
 /// Test the build system itself
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 4328c4e3f1d4c..5db9ac8295fb1 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -310,11 +310,18 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
     t!(fs::remove_dir_all(&image));
 }
 
+/// The path to the complete rustc-src tarball
 pub fn rust_src_location(build: &Build) -> PathBuf {
     let plain_name = format!("rustc-{}-src", build.rust_package_vers());
     distdir(build).join(&format!("{}.tar.gz", plain_name))
 }
 
+/// The path to the rust-src component installer
+pub fn rust_src_installer(build: &Build) -> PathBuf {
+    let name = pkgname(build, "rust-src");
+    distdir(build).join(&format!("{}.tar.gz", name))
+}
+
 /// Creates a tarball of save-analysis metadata, if available.
 pub fn analysis(build: &Build, compiler: &Compiler, target: &str) {
     assert!(build.config.extended);
@@ -369,13 +376,11 @@ pub fn rust_src(build: &Build) {
 
     println!("Dist src");
 
-    let name = pkgname(build, "rust-src");
-    let image = tmpdir(build).join(format!("{}-image", name));
-    let _ = fs::remove_dir_all(&image);
-
-    let dst = image.join("lib/rustlib/src");
-    let dst_src = dst.join("rust");
-    t!(fs::create_dir_all(&dst_src));
+    // Make sure that the root folder of tarball has the correct name
+    let plain_name = format!("rustc-{}-src", build.rust_package_vers());
+    let plain_dst_src = tmpdir(build).join(&plain_name);
+    let _ = fs::remove_dir_all(&plain_dst_src);
+    t!(fs::create_dir_all(&plain_dst_src));
 
     // This is the set of root paths which will become part of the source package
     let src_files = [
@@ -424,13 +429,13 @@ pub fn rust_src(build: &Build) {
 
     // Copy the directories using our filter
     for item in &src_dirs {
-        let dst = &dst_src.join(item);
+        let dst = &plain_dst_src.join(item);
         t!(fs::create_dir(dst));
         cp_filtered(&build.src.join(item), dst, &filter_fn);
     }
     // Copy the files normally
     for item in &src_files {
-        copy(&build.src.join(item), &dst_src.join(item));
+        copy(&build.src.join(item), &plain_dst_src.join(item));
     }
 
     // If we're building from git sources, we need to vendor a complete distribution.
@@ -455,10 +460,63 @@ pub fn rust_src(build: &Build) {
         // Vendor all Cargo dependencies
         let mut cmd = Command::new(&build.cargo);
         cmd.arg("vendor")
-           .current_dir(&dst_src.join("src"));
+           .current_dir(&plain_dst_src.join("src"));
         build.run(&mut cmd);
     }
 
+    // Create the version file
+    write_file(&plain_dst_src.join("version"), build.rust_version().as_bytes());
+
+    // Create plain source tarball
+    let tarball = rust_src_location(build);
+    if let Some(dir) = tarball.parent() {
+        t!(fs::create_dir_all(dir));
+    }
+    let mut cmd = Command::new("tar");
+    cmd.arg("-czf").arg(sanitize_sh(&tarball))
+       .arg(&plain_name)
+       .current_dir(tmpdir(build));
+    build.run(&mut cmd);
+
+
+    let name = pkgname(build, "rust-src");
+    let image = tmpdir(build).join(format!("{}-image", name));
+    let _ = fs::remove_dir_all(&image);
+
+    let dst = image.join("lib/rustlib/src");
+    let dst_src = dst.join("rust");
+    t!(fs::create_dir_all(&dst_src));
+
+    // This is the reduced set of paths which will become the rust-src component
+    // (essentially libstd and all of its path dependencies)
+    let std_src_dirs = [
+        "src/build_helper",
+        "src/liballoc",
+        "src/liballoc_jemalloc",
+        "src/liballoc_system",
+        "src/libcollections",
+        "src/libcompiler_builtins",
+        "src/libcore",
+        "src/liblibc",
+        "src/libpanic_abort",
+        "src/libpanic_unwind",
+        "src/librand",
+        "src/librustc_asan",
+        "src/librustc_lsan",
+        "src/librustc_msan",
+        "src/librustc_tsan",
+        "src/libstd",
+        "src/libstd_unicode",
+        "src/libunwind",
+        "src/rustc/libc_shim",
+    ];
+
+    for item in &std_src_dirs {
+        let dst = &dst_src.join(item);
+        t!(fs::create_dir_all(dst));
+        cp_r(&plain_dst_src.join(item), dst);
+    }
+
     // Create source tarball in rust-installer format
     let mut cmd = Command::new(SH_CMD);
     cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh")))
@@ -473,23 +531,6 @@ pub fn rust_src(build: &Build) {
        .arg("--legacy-manifest-dirs=rustlib,cargo");
     build.run(&mut cmd);
 
-    // Rename directory, so that root folder of tarball has the correct name
-    let plain_name = format!("rustc-{}-src", build.rust_package_vers());
-    let plain_dst_src = tmpdir(build).join(&plain_name);
-    let _ = fs::remove_dir_all(&plain_dst_src);
-    t!(fs::create_dir_all(&plain_dst_src));
-    cp_r(&dst_src, &plain_dst_src);
-
-    // Create the version file
-    write_file(&plain_dst_src.join("version"), build.rust_version().as_bytes());
-
-    // Create plain source tarball
-    let mut cmd = Command::new("tar");
-    cmd.arg("-czf").arg(sanitize_sh(&rust_src_location(build)))
-       .arg(&plain_name)
-       .current_dir(tmpdir(build));
-    build.run(&mut cmd);
-
     t!(fs::remove_dir_all(&image));
     t!(fs::remove_dir_all(&plain_dst_src));
 }