diff --git a/.gitmodules b/.gitmodules
index 65aafeea17bd9..fc2f8bbc8a350 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,10 +2,6 @@
 	path = src/llvm
 	url = https://github.com/rust-lang/llvm.git
 	branch = master
-[submodule "src/rt/hoedown"]
-	path = src/rt/hoedown
-	url = https://github.com/rust-lang/hoedown.git
-	branch = rust-2015-09-21-do-not-delete
 [submodule "src/jemalloc"]
 	path = src/jemalloc
 	url = https://github.com/rust-lang/jemalloc.git
diff --git a/COPYRIGHT b/COPYRIGHT
index f8b637d204ace..9bc018d983d7d 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -192,28 +192,6 @@ their own copyright notices and license terms:
     USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
     OF SUCH DAMAGE.
 
-* Hoedown, the markdown parser, under src/rt/hoedown, is
-  licensed as follows.
-
-    Copyright (c) 2008, Natacha Porté
-    Copyright (c) 2011, Vicent Martí
-    Copyright (c) 2013, Devin Torres and the Hoedown authors
-
-    Permission to use, copy, modify, and distribute this
-    software for any purpose with or without fee is hereby
-    granted, provided that the above copyright notice and
-    this permission notice appear in all copies.
-
-    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR
-    DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-    INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-    FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-    SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
-    ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
-    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-    OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-    CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
 * libbacktrace, under src/libbacktrace:
 
     Copyright (C) 2012-2014 Free Software Foundation, Inc.
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 4b3099eed016b..d8306c66daf84 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -480,30 +480,6 @@ dependencies = [
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "cssparser"
-version = "0.13.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "procedural-masquerade 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "cssparser-macros"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "procedural-masquerade 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "curl"
 version = "0.4.11"
@@ -533,14 +509,6 @@ dependencies = [
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "debug_unreachable"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "deglob"
 version = "0.1.0"
@@ -761,15 +729,6 @@ name = "fuchsia-zircon-sys"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "futf"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "futures"
 version = "0.1.17"
@@ -870,26 +829,6 @@ dependencies = [
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "html-diff"
-version = "0.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kuchiki 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "html5ever"
-version = "0.20.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "markup5ever 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "idna"
 version = "0.1.4"
@@ -1010,17 +949,6 @@ dependencies = [
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "kuchiki"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cssparser 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "html5ever 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "selectors 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "languageserver-types"
 version = "0.30.0"
@@ -1138,24 +1066,6 @@ dependencies = [
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "mac"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "markup5ever"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "matches"
 version = "0.1.6"
@@ -1440,50 +1350,11 @@ name = "pest"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "phf"
-version = "0.7.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "phf_codegen"
-version = "0.7.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "phf_generator"
-version = "0.7.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "phf_shared"
-version = "0.7.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "pkg-config"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "precomputed-hash"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "proc_macro"
 version = "0.0.0"
@@ -1493,11 +1364,6 @@ dependencies = [
  "syntax_pos 0.0.0",
 ]
 
-[[package]]
-name = "procedural-masquerade"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "profiler_builtins"
 version = "0.0.0"
@@ -2238,9 +2104,6 @@ dependencies = [
 name = "rustdoc"
 version = "0.0.0"
 dependencies = [
- "build_helper 0.1.0",
- "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "html-diff 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2322,21 +2185,6 @@ name = "scopeguard"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "selectors"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "semver"
 version = "0.6.0"
@@ -2435,16 +2283,6 @@ name = "shlex"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "siphasher"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "smallvec"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "smallvec"
 version = "0.6.0"
@@ -2495,36 +2333,6 @@ dependencies = [
  "core 0.0.0",
 ]
 
-[[package]]
-name = "string_cache"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "string_cache_codegen"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "string_cache_shared"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "strsim"
 version = "0.6.0"
@@ -2645,16 +2453,6 @@ dependencies = [
  "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "tendril"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "term"
 version = "0.0.0"
@@ -2803,14 +2601,6 @@ name = "unicode-xid"
 version = "0.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "unreachable"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "unreachable"
 version = "1.0.0"
@@ -2862,14 +2652,6 @@ dependencies = [
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "utf-8"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "utf8-ranges"
 version = "0.1.3"
@@ -3016,11 +2798,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be"
 "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
 "checksum crypto-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34903878eec1694faf53cae8473a088df333181de421d4d3d48061d6559fe602"
-"checksum cssparser 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef6124306e5ebc5ab11891d063aeafdd0cdc308079b708c8b566125f3680292b"
-"checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b70fd6394677d3c0e239ff4be6f2b3176e171ffd1c23ffdc541e78dea2b8bb5e"
 "checksum curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46e49c7125131f5afaded06944d6888b55cbdf8eba05dae73c954019b907961"
-"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3"
 "checksum derive-new 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "415f627ab054041c3eb748c2e1da0ef751989f5f0c386b63a098e545854a98ba"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
 "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
@@ -3044,7 +2823,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
-"checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3"
 "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1"
 "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9"
 "checksum git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5b4bb7cd2a44e6e5ee3a26ba6a9ca10d4ce2771cdc3839bbc54b47b7d1be84"
@@ -3056,8 +2834,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa"
 "checksum hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "459d3cf58137bb02ad4adeef5036377ff59f066dbb82517b7192e3a5462a2abc"
 "checksum home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f25ae61099d8f3fee8b483df0bd4ecccf4b2731897aad40d50eca1b641fe6db"
-"checksum html-diff 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4cfdf62a484a3ac0d9b80f562d37f99366db08a63621b917ea3056565345f7"
-"checksum html5ever 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bfb46978eb757a603b7dfe2dafb1c62cb4dee3428d8ac1de734d83d6b022d06"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
 "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8"
 "checksum ignore 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb2f0238094bd1b41800fb6eb9b16fdd5e9832ed6053ed91409f0cd5bf28dcfd"
@@ -3069,7 +2845,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483"
 "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-"checksum kuchiki 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e03098e8e719c92b7794515dfd5c1724e2b12f5ce1788e61cfa4663f82eba8d8"
 "checksum languageserver-types 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1541f9b22687f060511d213036e1f058797c48e3501e177f01cb6e88de802f5b"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
 "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
@@ -3082,8 +2857,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
 "checksum log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d382732ea0fbc09790c4899db3255bdea0fc78b54bf234bd18a63bb603915b6"
 "checksum lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b93b78f89e8737dac81837fc8f5521ac162abcba902e1a3db949d55346d1da"
-"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
-"checksum markup5ever 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "047150a0e03b57e638fc45af33a0b63a0362305d5b9f92ecef81df472a4cceb0"
 "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
 "checksum mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fef236caad7ba3b5b3944df946f19ab3e190bca53c111dd00fe05fa8d879f2fd"
 "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
@@ -3111,13 +2884,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6bf05dc61189828dfd7a59fd6e66d538e88d6b30390da1124a291e09fd3098b3"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8"
-"checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
-"checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
-"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
-"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
-"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
-"checksum procedural-masquerade 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1bcafee1590f81acb329ae45ec627b318123f085153913620316ae9a144b2a"
 "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b"
 "checksum pulldown-cmark 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a656fdb8b6848f896df5e478a0eb9083681663e37dcb77dd16981ff65329fe8b"
 "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
@@ -3154,7 +2921,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
 "checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
-"checksum selectors 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c89b1c6a3c029c82263f7dd2d44d0005ee7374eb09e254ab59dede4353a8c0"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
@@ -3167,14 +2933,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum shared_child 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "099b38928dbe4a0a01fcd8c233183072f14a7d126a34bed05880869be66e14cc"
 "checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8"
 "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
-"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
-"checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e"
 "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
 "checksum socket2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf5d5aa364bf61a0d744a293da20381617b6445b89eb524800fab857c5aed2d8"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
-"checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8"
-"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7"
-"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
@@ -3184,7 +2945,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76a302e717e348aa372ff577791c3832395650073b8d8432f8b3cb170b34afde"
 "checksum tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1605d3388ceb50252952ffebab4b5dc43017ead7e4481b175961c283bb951195"
 "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
-"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
 "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
 "checksum termcolor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9065bced9c3e43453aa3d56f1e98590b8455b341d2fa191a1090c0dd0b242c75"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
@@ -3202,12 +2962,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
 "checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb"
 "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
-"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
 "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
 "checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2"
 "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
 "checksum userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d28ea36bbd9192d75bd9fa9b39f96ddb986eaee824adae5d53b6e51919b2f3"
-"checksum utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f923c601c7ac48ef1d66f7d5b5b2d9a7ba9c51333ab75a3ddf8d0309185a56"
 "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
 "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index 389b504c64cdc..798d5c3eb6736 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -62,12 +62,9 @@ fn main() {
     // it up so we can make rustdoc print this into the docs
     if let Some(version) = env::var_os("RUSTDOC_CRATE_VERSION") {
         // This "unstable-options" can be removed when `--crate-version` is stabilized
-        cmd.arg("-Z").arg("unstable-options")
+        cmd.arg("-Z")
+           .arg("unstable-options")
            .arg("--crate-version").arg(version);
-
-        // While we can assume that `-Z unstable-options` is set, let's also force rustdoc to panic
-        // if pulldown rendering differences are found
-        cmd.arg("--deny-render-differences");
     }
 
     if verbose > 1 {
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index 919980be7df4e..ebb28c95b2ea6 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit 919980be7df4ea7d45a9dca8efc34da89bcf7d6b
+Subproject commit ebb28c95b2ea68b96eddb9e71aff4d32eacc74f0
diff --git a/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md b/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md
index dbaf91b6e78b2..ec9d85db107d4 100644
--- a/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md
+++ b/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md
@@ -6,7 +6,10 @@ With this feature gate enabled, one can use `?` as a Kleene operator meaning "0
 or 1 repetitions" in a macro definition. Previously only `+` and `*` were allowed.
 
 For example:
+
 ```rust
+#![feature(macro_at_most_once_rep)]
+
 macro_rules! foo {
     (something $(,)?) // `?` indicates `,` is "optional"...
         => {}
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 608adcb43d6c3..09d0a0f610b7b 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -2,7 +2,6 @@
 authors = ["The Rust Project Developers"]
 name = "rustdoc"
 version = "0.0.0"
-build = "build.rs"
 
 [lib]
 name = "rustdoc"
@@ -12,9 +11,4 @@ doctest = false
 
 [dependencies]
 pulldown-cmark = { version = "0.1.0", default-features = false }
-html-diff = "0.0.6"
 tempdir = "0.3"
-
-[build-dependencies]
-build_helper = { path = "../build_helper" }
-cc = "1.0.1"
diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs
deleted file mode 100644
index 276825bd31a75..0000000000000
--- a/src/librustdoc/build.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 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.
-
-extern crate build_helper;
-extern crate cc;
-
-fn main() {
-    let src_dir = std::path::Path::new("../rt/hoedown/src");
-    build_helper::rerun_if_changed_anything_in_dir(src_dir);
-    let mut cfg = cc::Build::new();
-    cfg.file("../rt/hoedown/src/autolink.c")
-       .file("../rt/hoedown/src/buffer.c")
-       .file("../rt/hoedown/src/document.c")
-       .file("../rt/hoedown/src/escape.c")
-       .file("../rt/hoedown/src/html.c")
-       .file("../rt/hoedown/src/html_blocks.c")
-       .file("../rt/hoedown/src/html_smartypants.c")
-       .file("../rt/hoedown/src/stack.c")
-       .file("../rt/hoedown/src/version.c")
-       .warnings(false)
-       .include(src_dir)
-       .warnings(false)
-       .compile("hoedown");
-}
-
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 66b5f3b5ea366..7f51b8f68ae49 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1050,7 +1050,7 @@ impl Clean<Attributes> for [ast::Attribute] {
 
         if UnstableFeatures::from_environment().is_nightly_build() {
             let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new);
-            for link in markdown_links(&dox, cx.render_type) {
+            for link in markdown_links(&dox) {
                 // bail early for real links
                 if link.contains('/') {
                     continue;
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 0674a0b5a3b10..81babd803a5e9 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -36,7 +36,6 @@ use std::path::PathBuf;
 use visit_ast::RustdocVisitor;
 use clean;
 use clean::Clean;
-use html::markdown::RenderType;
 use html::render::RenderInfo;
 
 pub use rustc::session::config::Input;
@@ -59,9 +58,6 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
     pub renderinfo: RefCell<RenderInfo>,
     /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
     pub external_traits: RefCell<FxHashMap<DefId, clean::Trait>>,
-    /// Which markdown renderer to use when extracting links.
-    pub render_type: RenderType,
-
     // The current set of type and lifetime substitutions,
     // for expanding type aliases at the HIR level:
 
@@ -111,8 +107,7 @@ pub fn run_core(search_paths: SearchPaths,
                 triple: Option<String>,
                 maybe_sysroot: Option<PathBuf>,
                 allow_warnings: bool,
-                force_unstable_if_unmarked: bool,
-                render_type: RenderType) -> (clean::Crate, RenderInfo)
+                force_unstable_if_unmarked: bool) -> (clean::Crate, RenderInfo)
 {
     // Parse, resolve, and typecheck the given crate.
 
@@ -242,7 +237,6 @@ pub fn run_core(search_paths: SearchPaths,
             access_levels: RefCell::new(access_levels),
             external_traits: Default::default(),
             renderinfo: Default::default(),
-            render_type,
             ty_substs: Default::default(),
             lt_substs: Default::default(),
             mod_ids: Default::default(),
diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs
index 03250542b4e79..6c328a87208aa 100644
--- a/src/librustdoc/externalfiles.rs
+++ b/src/librustdoc/externalfiles.rs
@@ -11,7 +11,7 @@
 use std::fs;
 use std::path::Path;
 use std::str;
-use html::markdown::{Markdown, RenderType};
+use html::markdown::Markdown;
 
 #[derive(Clone)]
 pub struct ExternalHtml {
@@ -28,7 +28,7 @@ pub struct ExternalHtml {
 
 impl ExternalHtml {
     pub fn load(in_header: &[String], before_content: &[String], after_content: &[String],
-                md_before_content: &[String], md_after_content: &[String], render: RenderType)
+                md_before_content: &[String], md_after_content: &[String])
             -> Option<ExternalHtml> {
         load_external_files(in_header)
             .and_then(|ih|
@@ -37,7 +37,7 @@ impl ExternalHtml {
             )
             .and_then(|(ih, bc)|
                 load_external_files(md_before_content)
-                    .map(|m_bc| (ih, format!("{}{}", bc, Markdown(&m_bc, &[], render))))
+                    .map(|m_bc| (ih, format!("{}{}", bc, Markdown(&m_bc, &[]))))
             )
             .and_then(|(ih, bc)|
                 load_external_files(after_content)
@@ -45,7 +45,7 @@ impl ExternalHtml {
             )
             .and_then(|(ih, bc, ac)|
                 load_external_files(md_after_content)
-                    .map(|m_ac| (ih, bc, format!("{}{}", ac, Markdown(&m_ac, &[], render))))
+                    .map(|m_ac| (ih, bc, format!("{}{}", ac, Markdown(&m_ac, &[]))))
             )
             .map(|(ih, bc, ac)|
                 ExternalHtml {
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 92b3a404c57a4..2913ea6a78ec3 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -25,8 +25,7 @@ use rustc::hir;
 use clean::{self, PrimitiveType};
 use core::DocAccessLevels;
 use html::item_type::ItemType;
-use html::render;
-use html::render::{cache, CURRENT_LOCATION_KEY};
+use html::render::{self, cache, CURRENT_LOCATION_KEY};
 
 /// Helper to render an optional visibility with a space after it (if the
 /// visibility is preset)
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 82ced00644da8..fedd802ce557f 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -18,18 +18,15 @@
 //! ```
 //! #![feature(rustc_private)]
 //!
-//! use rustdoc::html::markdown::{RenderType, Markdown};
+//! use rustdoc::html::markdown::Markdown;
 //!
 //! let s = "My *markdown* _text_";
-//! let html = format!("{}", Markdown(s, RenderType::Pulldown));
+//! let html = format!("{}", Markdown(s));
 //! // ... something using html
 //! ```
 
 #![allow(non_camel_case_types)]
 
-use libc;
-use std::slice;
-
 use std::cell::RefCell;
 use std::collections::{HashMap, VecDeque};
 use std::default::Default;
@@ -41,29 +38,21 @@ use syntax::codemap::Span;
 use html::render::derive_id;
 use html::toc::TocBuilder;
 use html::highlight;
-use html::escape::Escape;
 use test;
 
 use pulldown_cmark::{html, Event, Tag, Parser};
 use pulldown_cmark::{Options, OPTION_ENABLE_FOOTNOTES, OPTION_ENABLE_TABLES};
 
-#[derive(PartialEq, Debug, Clone, Copy)]
-pub enum RenderType {
-    Hoedown,
-    Pulldown,
-}
-
 /// A unit struct which has the `fmt::Display` trait implemented. When
 /// formatted, this struct will emit the HTML corresponding to the rendered
 /// version of the contained markdown string.
 /// The second parameter is a list of link replacements
-// The third parameter is whether we need a shorter version or not.
-pub struct Markdown<'a>(pub &'a str, pub &'a [(String, String)], pub RenderType);
+pub struct Markdown<'a>(pub &'a str, pub &'a [(String, String)]);
 /// A unit struct like `Markdown`, that renders the markdown with a
 /// table of contents.
-pub struct MarkdownWithToc<'a>(pub &'a str, pub RenderType);
+pub struct MarkdownWithToc<'a>(pub &'a str);
 /// A unit struct like `Markdown`, that renders the markdown escaping HTML tags.
-pub struct MarkdownHtml<'a>(pub &'a str, pub RenderType);
+pub struct MarkdownHtml<'a>(pub &'a str);
 /// A unit struct like `Markdown`, that renders only the first paragraph.
 pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]);
 
@@ -111,14 +100,6 @@ fn map_line(s: &str) -> Line {
     }
 }
 
-/// Returns a new string with all consecutive whitespace collapsed into
-/// single spaces.
-///
-/// Any leading or trailing whitespace will be trimmed.
-fn collapse_whitespace(s: &str) -> String {
-    s.split_whitespace().collect::<Vec<_>>().join(" ")
-}
-
 /// Convert chars from a title for an id.
 ///
 /// "Hello, world!" -> "hello-world"
@@ -453,543 +434,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
     }
 }
 
-const DEF_OUNIT: libc::size_t = 64;
-const HOEDOWN_EXT_NO_INTRA_EMPHASIS: libc::c_uint = 1 << 11;
-const HOEDOWN_EXT_TABLES: libc::c_uint = 1 << 0;
-const HOEDOWN_EXT_FENCED_CODE: libc::c_uint = 1 << 1;
-const HOEDOWN_EXT_AUTOLINK: libc::c_uint = 1 << 3;
-const HOEDOWN_EXT_STRIKETHROUGH: libc::c_uint = 1 << 4;
-const HOEDOWN_EXT_SUPERSCRIPT: libc::c_uint = 1 << 8;
-const HOEDOWN_EXT_FOOTNOTES: libc::c_uint = 1 << 2;
-const HOEDOWN_HTML_ESCAPE: libc::c_uint = 1 << 1;
-
-const HOEDOWN_EXTENSIONS: libc::c_uint =
-    HOEDOWN_EXT_NO_INTRA_EMPHASIS | HOEDOWN_EXT_TABLES |
-    HOEDOWN_EXT_FENCED_CODE | HOEDOWN_EXT_AUTOLINK |
-    HOEDOWN_EXT_STRIKETHROUGH | HOEDOWN_EXT_SUPERSCRIPT |
-    HOEDOWN_EXT_FOOTNOTES;
-
-enum hoedown_document {}
-
-type blockcodefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                 *const hoedown_buffer, *const hoedown_renderer_data,
-                                 libc::size_t);
-
-type blockquotefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                  *const hoedown_renderer_data, libc::size_t);
-
-type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                              libc::c_int, *const hoedown_renderer_data,
-                              libc::size_t);
-
-type blockhtmlfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                 *const hoedown_renderer_data, libc::size_t);
-
-type codespanfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                *const hoedown_renderer_data, libc::size_t) -> libc::c_int;
-
-type linkfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
-                             *const hoedown_buffer, *const hoedown_buffer,
-                             *const hoedown_renderer_data, libc::size_t) -> libc::c_int;
-
-type entityfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
-                               *const hoedown_renderer_data, libc::size_t);
-
-type normaltextfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                  *const hoedown_renderer_data, libc::size_t);
-
-#[repr(C)]
-struct hoedown_renderer_data {
-    opaque: *mut libc::c_void,
-}
-
-#[repr(C)]
-struct hoedown_renderer {
-    opaque: *mut libc::c_void,
-
-    blockcode: Option<blockcodefn>,
-    blockquote: Option<blockquotefn>,
-    header: Option<headerfn>,
-
-    other_block_level_callbacks: [libc::size_t; 11],
-
-    blockhtml: Option<blockhtmlfn>,
-
-    /* span level callbacks - NULL or return 0 prints the span verbatim */
-    autolink: libc::size_t, // unused
-    codespan: Option<codespanfn>,
-    other_span_level_callbacks_1: [libc::size_t; 7],
-    link: Option<linkfn>,
-    other_span_level_callbacks_2: [libc::size_t; 6],
-
-    /* low level callbacks - NULL copies input directly into the output */
-    entity: Option<entityfn>,
-    normal_text: Option<normaltextfn>,
-
-    /* header and footer */
-    other_callbacks: [libc::size_t; 2],
-}
-
-#[repr(C)]
-struct hoedown_html_renderer_state {
-    opaque: *mut libc::c_void,
-    toc_data: html_toc_data,
-    flags: libc::c_uint,
-    link_attributes: Option<extern "C" fn(*mut hoedown_buffer,
-                                          *const hoedown_buffer,
-                                          *const hoedown_renderer_data)>,
-}
-
-#[repr(C)]
-struct html_toc_data {
-    header_count: libc::c_int,
-    current_level: libc::c_int,
-    level_offset: libc::c_int,
-    nesting_level: libc::c_int,
-}
-
-#[repr(C)]
-struct hoedown_buffer {
-    data: *const u8,
-    size: libc::size_t,
-    asize: libc::size_t,
-    unit: libc::size_t,
-}
-
-struct MyOpaque {
-    dfltblk: extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                           *const hoedown_buffer, *const hoedown_renderer_data,
-                           libc::size_t),
-    toc_builder: Option<TocBuilder>,
-    links_out: Option<Vec<String>>,
-    links_replace: Vec<(String, String)>,
-}
-
-extern {
-    fn hoedown_html_renderer_new(render_flags: libc::c_uint,
-                                 nesting_level: libc::c_int)
-        -> *mut hoedown_renderer;
-    fn hoedown_html_renderer_free(renderer: *mut hoedown_renderer);
-
-    fn hoedown_document_new(rndr: *const hoedown_renderer,
-                            extensions: libc::c_uint,
-                            max_nesting: libc::size_t) -> *mut hoedown_document;
-    fn hoedown_document_render(doc: *mut hoedown_document,
-                               ob: *mut hoedown_buffer,
-                               document: *const u8,
-                               doc_size: libc::size_t);
-    fn hoedown_document_free(md: *mut hoedown_document);
-
-    fn hoedown_buffer_new(unit: libc::size_t) -> *mut hoedown_buffer;
-    fn hoedown_buffer_free(b: *mut hoedown_buffer);
-    fn hoedown_buffer_put(b: *mut hoedown_buffer, c: *const u8, len: libc::size_t);
-}
-
-impl hoedown_buffer {
-    fn as_bytes(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts(self.data, self.size as usize) }
-    }
-}
-
-extern fn hoedown_block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer,
-                        lang: *const hoedown_buffer, data: *const hoedown_renderer_data,
-                        line: libc::size_t) {
-    unsafe {
-        if orig_text.is_null() { return }
-
-        let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
-        let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque);
-        let text = (*orig_text).as_bytes();
-        let origtext = str::from_utf8(text).unwrap();
-        let origtext = origtext.trim_left();
-        debug!("docblock: ==============\n{:?}\n=======", text);
-        let mut compile_fail = false;
-        let mut ignore = false;
-
-        let rendered = if lang.is_null() || origtext.is_empty() {
-            false
-        } else {
-            let rlang = (*lang).as_bytes();
-            let rlang = str::from_utf8(rlang).unwrap();
-            let parse_result = LangString::parse(rlang);
-            compile_fail = parse_result.compile_fail;
-            ignore = parse_result.ignore;
-            if !parse_result.rust {
-                (my_opaque.dfltblk)(ob, orig_text, lang,
-                                    opaque as *const hoedown_renderer_data,
-                                    line);
-                true
-            } else {
-                false
-            }
-        };
-
-        let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
-        let text = lines.collect::<Vec<&str>>().join("\n");
-        if rendered { return }
-        PLAYGROUND.with(|play| {
-            // insert newline to clearly separate it from the
-            // previous block so we can shorten the html output
-            let mut s = String::from("\n");
-            let playground_button = play.borrow().as_ref().and_then(|&(ref krate, ref url)| {
-                if url.is_empty() {
-                    return None;
-                }
-                let test = origtext.lines()
-                    .map(|l| map_line(l).for_code())
-                    .collect::<Vec<&str>>().join("\n");
-                let krate = krate.as_ref().map(|s| &**s);
-                let (test, _) = test::make_test(&test, krate, false,
-                                                &Default::default());
-                let channel = if test.contains("#![feature(") {
-                    "&amp;version=nightly"
-                } else {
-                    ""
-                };
-                // These characters don't need to be escaped in a URI.
-                // FIXME: use a library function for percent encoding.
-                fn dont_escape(c: u8) -> bool {
-                    (b'a' <= c && c <= b'z') ||
-                    (b'A' <= c && c <= b'Z') ||
-                    (b'0' <= c && c <= b'9') ||
-                    c == b'-' || c == b'_' || c == b'.' ||
-                    c == b'~' || c == b'!' || c == b'\'' ||
-                    c == b'(' || c == b')' || c == b'*'
-                }
-                let mut test_escaped = String::new();
-                for b in test.bytes() {
-                    if dont_escape(b) {
-                        test_escaped.push(char::from(b));
-                    } else {
-                        write!(test_escaped, "%{:02X}", b).unwrap();
-                    }
-                }
-                Some(format!(
-                    r#"<a class="test-arrow" target="_blank" href="{}?code={}{}">Run</a>"#,
-                    url, test_escaped, channel
-                ))
-            });
-            let tooltip = if ignore {
-                Some(("This example is not tested", "ignore"))
-            } else if compile_fail {
-                Some(("This example deliberately fails to compile", "compile_fail"))
-            } else {
-                None
-            };
-            s.push_str(&highlight::render_with_highlighting(
-                           &text,
-                           Some(&format!("rust-example-rendered{}",
-                                         if ignore { " ignore" }
-                                         else if compile_fail { " compile_fail" }
-                                         else { "" })),
-                           None,
-                           playground_button.as_ref().map(String::as_str),
-                           tooltip));
-            hoedown_buffer_put(ob, s.as_ptr(), s.len());
-        })
-    }
-}
-
-extern fn hoedown_header(ob: *mut hoedown_buffer, text: *const hoedown_buffer,
-                         level: libc::c_int, data: *const hoedown_renderer_data,
-                         _: libc::size_t) {
-    // hoedown does this, we may as well too
-    unsafe { hoedown_buffer_put(ob, "\n".as_ptr(), 1); }
-
-    // Extract the text provided
-    let s = if text.is_null() {
-        "".to_owned()
-    } else {
-        let s = unsafe { (*text).as_bytes() };
-        str::from_utf8(&s).unwrap().to_owned()
-    };
-
-    // Discard '<em>', '<code>' tags and some escaped characters,
-    // transform the contents of the header into a hyphenated string
-    // without non-alphanumeric characters other than '-' and '_'.
-    //
-    // This is a terrible hack working around how hoedown gives us rendered
-    // html for text rather than the raw text.
-    let mut id = s.clone();
-    let repl_sub = vec!["<em>", "</em>", "<code>", "</code>",
-                        "<strong>", "</strong>",
-                        "&lt;", "&gt;", "&amp;", "&#39;", "&quot;"];
-    for sub in repl_sub {
-        id = id.replace(sub, "");
-    }
-    let id = id.chars().filter_map(|c| {
-        if c.is_alphanumeric() || c == '-' || c == '_' {
-            if c.is_ascii() {
-                Some(c.to_ascii_lowercase())
-            } else {
-                Some(c)
-            }
-        } else if c.is_whitespace() && c.is_ascii() {
-            Some('-')
-        } else {
-            None
-        }
-    }).collect::<String>();
-
-    let opaque = unsafe { (*data).opaque as *mut hoedown_html_renderer_state };
-    let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) };
-
-    let id = derive_id(id);
-
-    let sec = opaque.toc_builder.as_mut().map_or("".to_owned(), |builder| {
-        format!("{} ", builder.push(level as u32, s.clone(), id.clone()))
-    });
-
-    // Render the HTML
-    let text = format!("<h{lvl} id='{id}' class='section-header'>\
-                       <a href='#{id}'>{sec}{}</a></h{lvl}>",
-                       s, lvl = level, id = id, sec = sec);
-
-    unsafe { hoedown_buffer_put(ob, text.as_ptr(), text.len()); }
-}
-
-extern fn hoedown_codespan(
-    ob: *mut hoedown_buffer,
-    text: *const hoedown_buffer,
-    _: *const hoedown_renderer_data,
-    _: libc::size_t
-) -> libc::c_int {
-    let content = if text.is_null() {
-        "".to_owned()
-    } else {
-        let bytes = unsafe { (*text).as_bytes() };
-        let s = str::from_utf8(bytes).unwrap();
-        collapse_whitespace(s)
-    };
-
-    let content = format!("<code>{}</code>", Escape(&content));
-    unsafe {
-        hoedown_buffer_put(ob, content.as_ptr(), content.len());
-    }
-    // Return anything except 0, which would mean "also print the code span verbatim".
-    1
-}
-
-pub fn render(w: &mut fmt::Formatter,
-              s: &str,
-              links: &[(String, String)],
-              print_toc: bool,
-              html_flags: libc::c_uint) -> fmt::Result {
-    // copied from pulldown-cmark (MIT license, Google)
-    // https://github.com/google/pulldown-cmark
-    // this is temporary till we remove the hoedown renderer
-    static HREF_SAFE: [u8; 128] = [
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
-            0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-        ];
-
-    static HEX_CHARS: &'static [u8] = b"0123456789ABCDEF";
-
-    fn escape_href(ob: &mut String, s: &str) {
-        let mut mark = 0;
-        for i in 0..s.len() {
-            let c = s.as_bytes()[i];
-            if c >= 0x80 || HREF_SAFE[c as usize] == 0 {
-                // character needing escape
-
-                // write partial substring up to mark
-                if mark < i {
-                    ob.push_str(&s[mark..i]);
-                }
-                match c {
-                    b'&' => {
-                        ob.push_str("&amp;");
-                    },
-                    b'\'' => {
-                        ob.push_str("&#x27;");
-                    },
-                    _ => {
-                        let mut buf = [0u8; 3];
-                        buf[0] = b'%';
-                        buf[1] = HEX_CHARS[((c as usize) >> 4) & 0xF];
-                        buf[2] = HEX_CHARS[(c as usize) & 0xF];
-                        ob.push_str(str::from_utf8(&buf).unwrap());
-                    }
-                }
-                mark = i + 1;  // all escaped characters are ASCII
-            }
-        }
-        ob.push_str(&s[mark..]);
-    }
-    // end code copied from pulldown-cmark
-
-    extern fn hoedown_link(
-        ob: *mut hoedown_buffer,
-        content: *const hoedown_buffer,
-        link: *const hoedown_buffer,
-        title: *const hoedown_buffer,
-        data: *const hoedown_renderer_data,
-        _line: libc::size_t
-    ) -> libc::c_int {
-        if link.is_null() {
-            return 0;
-        }
-
-        let opaque = unsafe { (*data).opaque as *mut hoedown_html_renderer_state };
-        let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) };
-
-        let link = {
-            let s = unsafe { (*link).as_bytes() };
-            str::from_utf8(s).unwrap().to_owned()
-        };
-
-        let link = if let Some(&(_, ref new_target)) = opaque.links_replace
-                                                             .iter()
-                                                             .find(|t| &*t.0 == &*link) {
-            new_target.to_owned()
-        } else {
-            link
-        };
-
-        let content = unsafe {
-            content.as_ref().map(|c| {
-                let s = c.as_bytes();
-                str::from_utf8(s).unwrap().to_owned()
-            })
-        };
-
-        let mut link_buf = String::new();
-        escape_href(&mut link_buf, &link);
-
-        let title = unsafe {
-            title.as_ref().map(|t| {
-                let s = t.as_bytes();
-                str::from_utf8(s).unwrap().to_owned()
-            })
-        };
-
-        let link_out = format!("<a href=\"{link}\"{title}>{content}</a>",
-                               link = link_buf,
-                               title = title.map_or(String::new(),
-                                                    |t| format!(" title=\"{}\"", Escape(&t))),
-                               content = content.unwrap_or(String::new()));
-
-        unsafe { hoedown_buffer_put(ob, link_out.as_ptr(), link_out.len()); }
-
-        //return "anything but 0" to show we've written the link in
-        1
-    }
-
-    unsafe {
-        let ob = hoedown_buffer_new(DEF_OUNIT);
-        let renderer = hoedown_html_renderer_new(html_flags, 0);
-        let mut opaque = MyOpaque {
-            dfltblk: (*renderer).blockcode.unwrap(),
-            toc_builder: if print_toc {Some(TocBuilder::new())} else {None},
-            links_out: None,
-            links_replace: links.to_vec(),
-        };
-        (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
-                = &mut opaque as *mut _ as *mut libc::c_void;
-        (*renderer).blockcode = Some(hoedown_block);
-        (*renderer).header = Some(hoedown_header);
-        (*renderer).codespan = Some(hoedown_codespan);
-        (*renderer).link = Some(hoedown_link);
-
-        let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
-        hoedown_document_render(document, ob, s.as_ptr(),
-                                s.len() as libc::size_t);
-        hoedown_document_free(document);
-
-        hoedown_html_renderer_free(renderer);
-
-        let mut ret = opaque.toc_builder.map_or(Ok(()), |builder| {
-            write!(w, "<nav id=\"TOC\">{}</nav>", builder.into_toc())
-        });
-
-        if ret.is_ok() {
-            let buf = (*ob).as_bytes();
-            ret = w.write_str(str::from_utf8(buf).unwrap());
-        }
-        hoedown_buffer_free(ob);
-        ret
-    }
-}
-
-pub fn old_find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
-    extern fn block(_ob: *mut hoedown_buffer,
-                    text: *const hoedown_buffer,
-                    lang: *const hoedown_buffer,
-                    data: *const hoedown_renderer_data,
-                    line: libc::size_t) {
-        unsafe {
-            if text.is_null() { return }
-            let block_info = if lang.is_null() {
-                LangString::all_false()
-            } else {
-                let lang = (*lang).as_bytes();
-                let s = str::from_utf8(lang).unwrap();
-                LangString::parse(s)
-            };
-            if !block_info.rust { return }
-            let text = (*text).as_bytes();
-            let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
-            let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
-            let text = str::from_utf8(text).unwrap();
-            let lines = text.lines().map(|l| map_line(l).for_code());
-            let text = lines.collect::<Vec<&str>>().join("\n");
-            let filename = tests.get_filename();
-
-            if tests.render_type == RenderType::Hoedown {
-                let line = tests.get_line() + line;
-                tests.add_test(text.to_owned(),
-                               block_info.should_panic, block_info.no_run,
-                               block_info.ignore, block_info.test_harness,
-                               block_info.compile_fail, block_info.error_codes,
-                               line, filename, block_info.allow_fail);
-            } else {
-                tests.add_old_test(text, filename);
-            }
-        }
-    }
-
-    extern fn header(_ob: *mut hoedown_buffer,
-                     text: *const hoedown_buffer,
-                     level: libc::c_int, data: *const hoedown_renderer_data,
-                     _: libc::size_t) {
-        unsafe {
-            let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
-            let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
-            if text.is_null() {
-                tests.register_header("", level as u32);
-            } else {
-                let text = (*text).as_bytes();
-                let text = str::from_utf8(text).unwrap();
-                tests.register_header(text, level as u32);
-            }
-        }
-    }
-
-    tests.set_position(position);
-    unsafe {
-        let ob = hoedown_buffer_new(DEF_OUNIT);
-        let renderer = hoedown_html_renderer_new(0, 0);
-        (*renderer).blockcode = Some(block);
-        (*renderer).header = Some(header);
-        (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
-                = tests as *mut _ as *mut libc::c_void;
-
-        let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
-        hoedown_document_render(document, ob, doc.as_ptr(),
-                                doc.len() as libc::size_t);
-        hoedown_document_free(document);
-
-        hoedown_html_renderer_free(renderer);
-        hoedown_buffer_free(ob);
-    }
-}
-
 pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
     tests.set_position(position);
 
@@ -1139,88 +583,76 @@ impl LangString {
 
 impl<'a> fmt::Display for Markdown<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        let Markdown(md, links, render_type) = *self;
+        let Markdown(md, links) = *self;
 
         // This is actually common enough to special-case
         if md.is_empty() { return Ok(()) }
-        if render_type == RenderType::Hoedown {
-            render(fmt, md, links, false, 0)
-        } else {
-            let mut opts = Options::empty();
-            opts.insert(OPTION_ENABLE_TABLES);
-            opts.insert(OPTION_ENABLE_FOOTNOTES);
+        let mut opts = Options::empty();
+        opts.insert(OPTION_ENABLE_TABLES);
+        opts.insert(OPTION_ENABLE_FOOTNOTES);
 
-            let p = Parser::new_ext(md, opts);
+        let p = Parser::new_ext(md, opts);
 
-            let mut s = String::with_capacity(md.len() * 3 / 2);
+        let mut s = String::with_capacity(md.len() * 3 / 2);
 
-            html::push_html(&mut s,
-                            Footnotes::new(
-                                CodeBlocks::new(
-                                    LinkReplacer::new(
-                                        HeadingLinks::new(p, None),
-                                        links))));
+        html::push_html(&mut s,
+                        Footnotes::new(
+                            CodeBlocks::new(
+                                LinkReplacer::new(
+                                    HeadingLinks::new(p, None),
+                                    links))));
 
-            fmt.write_str(&s)
-        }
+        fmt.write_str(&s)
     }
 }
 
 impl<'a> fmt::Display for MarkdownWithToc<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        let MarkdownWithToc(md, render_type) = *self;
+        let MarkdownWithToc(md) = *self;
 
-        if render_type == RenderType::Hoedown {
-            render(fmt, md, &[], true, 0)
-        } else {
-            let mut opts = Options::empty();
-            opts.insert(OPTION_ENABLE_TABLES);
-            opts.insert(OPTION_ENABLE_FOOTNOTES);
+        let mut opts = Options::empty();
+        opts.insert(OPTION_ENABLE_TABLES);
+        opts.insert(OPTION_ENABLE_FOOTNOTES);
 
-            let p = Parser::new_ext(md, opts);
+        let p = Parser::new_ext(md, opts);
 
-            let mut s = String::with_capacity(md.len() * 3 / 2);
+        let mut s = String::with_capacity(md.len() * 3 / 2);
 
-            let mut toc = TocBuilder::new();
+        let mut toc = TocBuilder::new();
 
-            html::push_html(&mut s,
-                            Footnotes::new(CodeBlocks::new(HeadingLinks::new(p, Some(&mut toc)))));
+        html::push_html(&mut s,
+                        Footnotes::new(CodeBlocks::new(HeadingLinks::new(p, Some(&mut toc)))));
 
-            write!(fmt, "<nav id=\"TOC\">{}</nav>", toc.into_toc())?;
+        write!(fmt, "<nav id=\"TOC\">{}</nav>", toc.into_toc())?;
 
-            fmt.write_str(&s)
-        }
+        fmt.write_str(&s)
     }
 }
 
 impl<'a> fmt::Display for MarkdownHtml<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        let MarkdownHtml(md, render_type) = *self;
+        let MarkdownHtml(md) = *self;
 
         // This is actually common enough to special-case
         if md.is_empty() { return Ok(()) }
-        if render_type == RenderType::Hoedown {
-            render(fmt, md, &[], false, HOEDOWN_HTML_ESCAPE)
-        } else {
-            let mut opts = Options::empty();
-            opts.insert(OPTION_ENABLE_TABLES);
-            opts.insert(OPTION_ENABLE_FOOTNOTES);
+        let mut opts = Options::empty();
+        opts.insert(OPTION_ENABLE_TABLES);
+        opts.insert(OPTION_ENABLE_FOOTNOTES);
 
-            let p = Parser::new_ext(md, opts);
+        let p = Parser::new_ext(md, opts);
 
-            // Treat inline HTML as plain text.
-            let p = p.map(|event| match event {
-                Event::Html(text) | Event::InlineHtml(text) => Event::Text(text),
-                _ => event
-            });
+        // Treat inline HTML as plain text.
+        let p = p.map(|event| match event {
+            Event::Html(text) | Event::InlineHtml(text) => Event::Text(text),
+            _ => event
+        });
 
-            let mut s = String::with_capacity(md.len() * 3 / 2);
+        let mut s = String::with_capacity(md.len() * 3 / 2);
 
-            html::push_html(&mut s,
-                            Footnotes::new(CodeBlocks::new(HeadingLinks::new(p, None))));
+        html::push_html(&mut s,
+                        Footnotes::new(CodeBlocks::new(HeadingLinks::new(p, None))));
 
-            fmt.write_str(&s)
-        }
+        fmt.write_str(&s)
     }
 }
 
@@ -1290,95 +722,34 @@ pub fn plain_summary_line(md: &str) -> String {
     s
 }
 
-pub fn markdown_links(md: &str, render_type: RenderType) -> Vec<String> {
+pub fn markdown_links(md: &str) -> Vec<String> {
     if md.is_empty() {
         return vec![];
     }
 
-    match render_type {
-        RenderType::Hoedown => {
-            extern fn hoedown_link(
-                _ob: *mut hoedown_buffer,
-                _content: *const hoedown_buffer,
-                link: *const hoedown_buffer,
-                _title: *const hoedown_buffer,
-                data: *const hoedown_renderer_data,
-                _line: libc::size_t
-            ) -> libc::c_int {
-                if link.is_null() {
-                    return 0;
-                }
-
-                let opaque = unsafe { (*data).opaque as *mut hoedown_html_renderer_state };
-                let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) };
-
-                if let Some(ref mut links) = opaque.links_out {
-                    let s = unsafe { (*link).as_bytes() };
-                    let s = str::from_utf8(&s).unwrap().to_owned();
-
-                    debug!("found link: {}", s);
-
-                    links.push(s);
-                }
-
-                //returning 0 here means "emit the span verbatim", but we're not using the output
-                //anyway so we don't really care
-                0
-            }
-
-            unsafe {
-                let ob = hoedown_buffer_new(DEF_OUNIT);
-                let renderer = hoedown_html_renderer_new(0, 0);
-                let mut opaque = MyOpaque {
-                    dfltblk: (*renderer).blockcode.unwrap(),
-                    toc_builder: None,
-                    links_out: Some(vec![]),
-                    links_replace: vec![],
-                };
-                (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
-                        = &mut opaque as *mut _ as *mut libc::c_void;
-                (*renderer).header = Some(hoedown_header);
-                (*renderer).codespan = Some(hoedown_codespan);
-                (*renderer).link = Some(hoedown_link);
+    let mut opts = Options::empty();
+    opts.insert(OPTION_ENABLE_TABLES);
+    opts.insert(OPTION_ENABLE_FOOTNOTES);
 
-                let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
-                hoedown_document_render(document, ob, md.as_ptr(),
-                                        md.len() as libc::size_t);
-                hoedown_document_free(document);
+    let p = Parser::new_ext(md, opts);
 
-                hoedown_html_renderer_free(renderer);
-                hoedown_buffer_free(ob);
+    let iter = Footnotes::new(HeadingLinks::new(p, None));
+    let mut links = vec![];
 
-                opaque.links_out.unwrap()
-            }
-        }
-        RenderType::Pulldown => {
-            let mut opts = Options::empty();
-            opts.insert(OPTION_ENABLE_TABLES);
-            opts.insert(OPTION_ENABLE_FOOTNOTES);
-
-            let p = Parser::new_ext(md, opts);
-
-            let iter = Footnotes::new(HeadingLinks::new(p, None));
-            let mut links = vec![];
-
-            for ev in iter {
-                if let Event::Start(Tag::Link(dest, _)) = ev {
-                    debug!("found link: {}", dest);
-                    links.push(dest.into_owned());
-                }
-            }
-
-            links
+    for ev in iter {
+        if let Event::Start(Tag::Link(dest, _)) = ev {
+            debug!("found link: {}", dest);
+            links.push(dest.into_owned());
         }
     }
+
+    links
 }
 
 #[cfg(test)]
 mod tests {
     use super::{LangString, Markdown, MarkdownHtml};
     use super::plain_summary_line;
-    use super::RenderType;
     use html::render::reset_ids;
 
     #[test]
@@ -1425,14 +796,14 @@ mod tests {
     #[test]
     fn issue_17736() {
         let markdown = "# title";
-        format!("{}", Markdown(markdown, &[], RenderType::Pulldown));
+        format!("{}", Markdown(markdown, &[]));
         reset_ids(true);
     }
 
     #[test]
     fn test_header() {
         fn t(input: &str, expect: &str) {
-            let output = format!("{}", Markdown(input, &[], RenderType::Pulldown));
+            let output = format!("{}", Markdown(input, &[]));
             assert_eq!(output, expect, "original: {}", input);
             reset_ids(true);
         }
@@ -1454,7 +825,7 @@ mod tests {
     #[test]
     fn test_header_ids_multiple_blocks() {
         fn t(input: &str, expect: &str) {
-            let output = format!("{}", Markdown(input, &[], RenderType::Pulldown));
+            let output = format!("{}", Markdown(input, &[]));
             assert_eq!(output, expect, "original: {}", input);
         }
 
@@ -1495,7 +866,7 @@ mod tests {
     #[test]
     fn test_markdown_html_escape() {
         fn t(input: &str, expect: &str) {
-            let output = format!("{}", MarkdownHtml(input, RenderType::Pulldown));
+            let output = format!("{}", MarkdownHtml(input));
             assert_eq!(output, expect, "original: {}", input);
         }
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 1fb8f106cac03..d6025920e78b0 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -62,7 +62,7 @@ use rustc::hir;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_data_structures::flock;
 
-use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability, Span};
+use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability};
 use doctree;
 use fold::DocFolder;
 use html::escape::Escape;
@@ -71,11 +71,9 @@ use html::format::{TyParamBounds, WhereClause, href, AbiSpace};
 use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
 use html::format::fmt_impl_for_trait_page;
 use html::item_type::ItemType;
-use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine, RenderType};
+use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine};
 use html::{highlight, layout};
 
-use html_diff;
-
 /// A pair of name and its optional document.
 pub type NameDoc = (String, Option<String>);
 
@@ -99,7 +97,6 @@ pub struct Context {
     /// publicly reused items to redirect to the right location.
     pub render_redirect_pages: bool,
     pub shared: Arc<SharedContext>,
-    pub render_type: RenderType,
 }
 
 pub struct SharedContext {
@@ -123,9 +120,6 @@ pub struct SharedContext {
     /// The given user css file which allow to customize the generated
     /// documentation theme.
     pub css_file_extension: Option<PathBuf>,
-    /// Warnings for the user if rendering would differ using different markdown
-    /// parsers.
-    pub markdown_warnings: RefCell<Vec<(Span, String, Vec<html_diff::Difference>)>>,
     /// The directories that have already been created in this doc run. Used to reduce the number
     /// of spurious `create_dir_all` calls.
     pub created_dirs: RefCell<FxHashSet<PathBuf>>,
@@ -426,23 +420,9 @@ impl ToJson for IndexItemFunctionType {
     }
 }
 
-// TLS keys used to carry information around during rendering.
-
 thread_local!(static CACHE_KEY: RefCell<Arc<Cache>> = Default::default());
-thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> =
-                    RefCell::new(Vec::new()));
-thread_local!(pub static USED_ID_MAP: RefCell<FxHashMap<String, usize>> =
-                    RefCell::new(init_ids()));
-
-pub fn render_text<T, F: FnMut(RenderType) -> T>(mut render: F) -> (T, T) {
-    // Save the state of USED_ID_MAP so it only gets updated once even
-    // though we're rendering twice.
-    let orig_used_id_map = USED_ID_MAP.with(|map| map.borrow().clone());
-    let hoedown_output = render(RenderType::Hoedown);
-    USED_ID_MAP.with(|map| *map.borrow_mut() = orig_used_id_map);
-    let pulldown_output = render(RenderType::Pulldown);
-    (hoedown_output, pulldown_output)
-}
+thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> = RefCell::new(Vec::new()));
+thread_local!(pub static USED_ID_MAP: RefCell<FxHashMap<String, usize>> = RefCell::new(init_ids()));
 
 fn init_ids() -> FxHashMap<String, usize> {
     [
@@ -500,9 +480,7 @@ pub fn run(mut krate: clean::Crate,
            passes: FxHashSet<String>,
            css_file_extension: Option<PathBuf>,
            renderinfo: RenderInfo,
-           render_type: RenderType,
            sort_modules_alphabetically: bool,
-           deny_render_differences: bool,
            themes: Vec<PathBuf>) -> Result<(), Error> {
     let src_root = match krate.src {
         FileName::Real(ref p) => match p.parent() {
@@ -524,7 +502,6 @@ pub fn run(mut krate: clean::Crate,
             krate: krate.name.clone(),
         },
         css_file_extension: css_file_extension.clone(),
-        markdown_warnings: RefCell::new(vec![]),
         created_dirs: RefCell::new(FxHashSet()),
         sort_modules_alphabetically,
         themes,
@@ -572,7 +549,6 @@ pub fn run(mut krate: clean::Crate,
         dst,
         render_redirect_pages: false,
         shared: Arc::new(scx),
-        render_type,
     };
 
     // Crawl the crate to build various caches used for the output
@@ -655,141 +631,8 @@ pub fn run(mut krate: clean::Crate,
 
     write_shared(&cx, &krate, &*cache, index)?;
 
-    let scx = cx.shared.clone();
-
     // And finally render the whole crate's documentation
-    let result = cx.krate(krate);
-
-    let markdown_warnings = scx.markdown_warnings.borrow();
-    if !markdown_warnings.is_empty() {
-        let mut intro_msg = false;
-        for &(ref span, ref text, ref diffs) in &*markdown_warnings {
-            for d in diffs {
-                render_difference(d, &mut intro_msg, span, text);
-            }
-        }
-
-        if deny_render_differences {
-            println!("Aborting with {} rendering differences", markdown_warnings.len());
-            ::std::process::exit(1);
-        }
-    }
-
-    result
-}
-
-// A short, single-line view of `s`.
-fn concise_str(mut s: &str) -> String {
-    if s.contains('\n') {
-        s = s.lines().next().expect("Impossible! We just found a newline");
-    }
-    if s.len() > 70 {
-        let mut lo = 50;
-        let mut hi = s.len() - 20;
-        while !s.is_char_boundary(lo) {
-            lo -= 1;
-        }
-        while !s.is_char_boundary(hi) {
-            hi += 1;
-        }
-        return format!("{} ... {}", &s[..lo], &s[hi..]);
-    }
-    s.to_owned()
-}
-
-// Returns short versions of s1 and s2, starting from where the strings differ.
-fn concise_compared_strs(s1: &str, s2: &str) -> (String, String) {
-    let s1 = s1.trim();
-    let s2 = s2.trim();
-    if !s1.contains('\n') && !s2.contains('\n') && s1.len() <= 70 && s2.len() <= 70 {
-        return (s1.to_owned(), s2.to_owned());
-    }
-
-    let mut start_byte = 0;
-    for (c1, c2) in s1.chars().zip(s2.chars()) {
-        if c1 != c2 {
-            break;
-        }
-
-        start_byte += c1.len_utf8();
-    }
-
-    if start_byte == 0 {
-        return (concise_str(s1), concise_str(s2));
-    }
-
-    let s1 = &s1[start_byte..];
-    let s2 = &s2[start_byte..];
-    (format!("...{}", concise_str(s1)), format!("...{}", concise_str(s2)))
-}
-
-fn print_message(msg: &str, intro_msg: &mut bool, span: &Span, text: &str) {
-    if !*intro_msg {
-        println!("WARNING: documentation for this crate may be rendered \
-                  differently using the new Pulldown renderer.");
-        println!("    See https://github.com/rust-lang/rust/issues/44229 for details.");
-        *intro_msg = true;
-    }
-    println!("WARNING: rendering difference in `{}`", concise_str(text));
-    println!("   --> {}:{}:{}", span.filename, span.loline, span.locol);
-    println!("{}", msg);
-}
-
-pub fn render_difference(diff: &html_diff::Difference,
-                         intro_msg: &mut bool,
-                         span: &Span,
-                         text: &str) {
-    match *diff {
-        html_diff::Difference::NodeType { ref elem, ref opposite_elem } => {
-            print_message(&format!("    {} Types differ: expected: `{}`, found: `{}`",
-                                   elem.path, elem.element_name, opposite_elem.element_name),
-                          intro_msg, span, text);
-        }
-        html_diff::Difference::NodeName { ref elem, ref opposite_elem } => {
-            print_message(&format!("    {} Tags differ: expected: `{}`, found: `{}`",
-                                   elem.path, elem.element_name, opposite_elem.element_name),
-                          intro_msg, span, text);
-        }
-        html_diff::Difference::NodeAttributes { ref elem,
-                                                ref elem_attributes,
-                                                ref opposite_elem_attributes,
-                                                .. } => {
-            print_message(&format!("    {} Attributes differ in `{}`: expected: `{:?}`, \
-                                    found: `{:?}`",
-                                   elem.path, elem.element_name, elem_attributes,
-                                   opposite_elem_attributes),
-                          intro_msg, span, text);
-        }
-        html_diff::Difference::NodeText { ref elem, ref elem_text, ref opposite_elem_text, .. } => {
-            if elem_text.split("\n")
-                        .zip(opposite_elem_text.split("\n"))
-                        .any(|(a, b)| a.trim() != b.trim()) {
-                let (s1, s2) = concise_compared_strs(elem_text, opposite_elem_text);
-                print_message(&format!("    {} Text differs:\n        expected: `{}`\n        \
-                                        found:    `{}`",
-                                       elem.path, s1, s2),
-                              intro_msg, span, text);
-            }
-        }
-        html_diff::Difference::NotPresent { ref elem, ref opposite_elem } => {
-            if let Some(ref elem) = *elem {
-                print_message(&format!("    {} One element is missing: expected: `{}`",
-                                       elem.path, elem.element_name),
-                              intro_msg, span, text);
-            } else if let Some(ref elem) = *opposite_elem {
-                if elem.element_name.is_empty() {
-                    print_message(&format!("    {} One element is missing: expected: `{}`",
-                                           elem.path, concise_str(&elem.element_content)),
-                                  intro_msg, span, text);
-                } else {
-                    print_message(&format!("    {} Unexpected element `{}`: found: `{}`",
-                                           elem.path, elem.element_name,
-                                           concise_str(&elem.element_content)),
-                                  intro_msg, span, text);
-                }
-            }
-        }
-    }
+    cx.krate(krate)
 }
 
 /// Build the search index from the collected metadata
@@ -1929,42 +1772,17 @@ fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Re
     Ok(())
 }
 
-/// Render md_text as markdown. Warns the user if there are difference in
-/// rendering between Pulldown and Hoedown.
+/// Render md_text as markdown.
 fn render_markdown(w: &mut fmt::Formatter,
                    md_text: &str,
                    links: Vec<(String, String)>,
-                   span: Span,
-                   render_type: RenderType,
-                   prefix: &str,
-                   scx: &SharedContext)
+                   prefix: &str,)
                    -> fmt::Result {
-    let (hoedown_output, pulldown_output) =
-        render_text(|ty| format!("{}", Markdown(md_text, &links, ty)));
-    let mut differences = html_diff::get_differences(&pulldown_output, &hoedown_output);
-    differences.retain(|s| {
-        match *s {
-            html_diff::Difference::NodeText { ref elem_text,
-                                              ref opposite_elem_text,
-                                              .. }
-                if elem_text.split_whitespace().eq(opposite_elem_text.split_whitespace()) => {
-                    false
-            }
-            _ => true,
-        }
-    });
-
-    if !differences.is_empty() {
-        scx.markdown_warnings.borrow_mut().push((span, md_text.to_owned(), differences));
-    }
-
-    write!(w, "<div class='docblock'>{}{}</div>",
-           prefix,
-           if render_type == RenderType::Pulldown { pulldown_output } else { hoedown_output })
+    write!(w, "<div class='docblock'>{}{}</div>", prefix, Markdown(md_text, &links))
 }
 
 fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLink,
-                  cx: &Context, prefix: &str) -> fmt::Result {
+                  prefix: &str) -> fmt::Result {
     if let Some(s) = item.doc_value() {
         let markdown = if s.contains('\n') {
             format!("{} [Read more]({})",
@@ -1972,13 +1790,7 @@ fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLin
         } else {
             format!("{}", &plain_summary_line(Some(s)))
         };
-        render_markdown(w,
-                        &markdown,
-                        item.links(),
-                        item.source.clone(),
-                        cx.render_type,
-                        prefix,
-                        &cx.shared)?;
+        render_markdown(w, &markdown, item.links(), prefix)?;
     } else if !prefix.is_empty() {
         write!(w, "<div class='docblock'>{}</div>", prefix)?;
     }
@@ -2004,13 +1816,7 @@ fn document_full(w: &mut fmt::Formatter, item: &clean::Item,
                  cx: &Context, prefix: &str) -> fmt::Result {
     if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) {
         debug!("Doc block: =====\n{}\n=====", s);
-        render_markdown(w,
-                        &*s,
-                        item.links(),
-                        item.source.clone(),
-                        cx.render_type,
-                        prefix,
-                        &cx.shared)?;
+        render_markdown(w, &*s, item.links(), prefix)?;
     } else if !prefix.is_empty() {
         write!(w, "<div class='docblock'>{}</div>", prefix)?;
     }
@@ -2230,13 +2036,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
                        </tr>",
                        name = *myitem.name.as_ref().unwrap(),
                        stab_docs = stab_docs,
-                       docs = if cx.render_type == RenderType::Hoedown {
-                           format!("{}",
-                                   shorter(Some(&Markdown(doc_value, &myitem.links(),
-                                                          RenderType::Hoedown).to_string())))
-                       } else {
-                           format!("{}", MarkdownSummaryLine(doc_value, &myitem.links()))
-                       },
+                       docs = MarkdownSummaryLine(doc_value, &myitem.links()),
                        class = myitem.type_(),
                        stab = myitem.stability_class().unwrap_or("".to_string()),
                        unsafety_flag = unsafety_flag,
@@ -2270,7 +2070,7 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
             };
             let text = format!("Deprecated{}{}",
                                since,
-                               MarkdownHtml(&deprecated_reason, cx.render_type));
+                               MarkdownHtml(&deprecated_reason));
             stability.push(format!("<div class='stab deprecated'>{}</div>", text))
         };
 
@@ -2300,7 +2100,7 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
                                         This is a nightly-only experimental API. {}\
                                         </summary>{}",
                                        unstable_extra,
-                                       MarkdownHtml(&stab.unstable_reason, cx.render_type));
+                                       MarkdownHtml(&stab.unstable_reason));
                     stability.push(format!("<div class='stab unstable'><details>{}</details></div>",
                                    text));
                 }
@@ -2320,7 +2120,7 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
             String::new()
         };
 
-        let text = format!("Deprecated{}{}", since, MarkdownHtml(&note, cx.render_type));
+        let text = format!("Deprecated{}{}", since, MarkdownHtml(&note));
         stability.push(format!("<div class='stab deprecated'>{}</div>", text))
     }
 
@@ -3426,7 +3226,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
         write!(w, "</h3>\n")?;
         if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
             write!(w, "<div class='docblock'>{}</div>",
-                   Markdown(&*dox, &i.impl_item.links(), cx.render_type))?;
+                   Markdown(&*dox, &i.impl_item.links()))?;
         }
     }
 
@@ -3511,7 +3311,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
                         } else if show_def_docs {
                             // In case the item isn't documented,
                             // provide short documentation from the trait.
-                            document_short(w, it, link, cx, &prefix)?;
+                            document_short(w, it, link, &prefix)?;
                         }
                     }
                 } else {
@@ -3523,7 +3323,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
             } else {
                 document_stability(w, cx, item)?;
                 if show_def_docs {
-                    document_short(w, item, link, cx, &prefix)?;
+                    document_short(w, item, link, &prefix)?;
                 }
             }
         }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index a72026c7d6b27..825558648e1f8 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -19,7 +19,6 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(fs_read_write)]
-#![feature(libc)]
 #![feature(set_stdio)]
 #![feature(slice_patterns)]
 #![feature(test)]
@@ -29,8 +28,6 @@
 extern crate arena;
 extern crate getopts;
 extern crate env_logger;
-extern crate html_diff;
-extern crate libc;
 extern crate rustc;
 extern crate rustc_data_structures;
 extern crate rustc_const_math;
@@ -65,8 +62,7 @@ use std::sync::mpsc::channel;
 
 use externalfiles::ExternalHtml;
 use rustc::session::search_paths::SearchPaths;
-use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options,
-                             Externs};
+use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options, Externs};
 
 #[macro_use]
 pub mod externalfiles;
@@ -95,8 +91,6 @@ pub mod theme;
 
 use clean::AttributesExt;
 
-use html::markdown::RenderType;
-
 struct Output {
     krate: clean::Crate,
     renderinfo: html::render::RenderInfo,
@@ -243,9 +237,6 @@ pub fn opts() -> Vec<RustcOptGroup> {
                       or `#![doc(html_playground_url=...)]`",
                      "URL")
         }),
-        unstable("disable-commonmark", |o| {
-            o.optflag("", "disable-commonmark", "to disable commonmark doc rendering/testing")
-        }),
         unstable("display-warnings", |o| {
             o.optflag("", "display-warnings", "to print code warnings when testing doc")
         }),
@@ -259,10 +250,6 @@ pub fn opts() -> Vec<RustcOptGroup> {
             o.optflag("", "sort-modules-by-appearance", "sort modules by where they appear in the \
                                                          program, rather than alphabetically")
         }),
-        unstable("deny-render-differences", |o| {
-            o.optflag("", "deny-render-differences", "abort doc runs when markdown rendering \
-                                                      differences are found")
-        }),
         unstable("themes", |o| {
             o.optmulti("", "themes",
                        "additional themes which will be added to the generated docs",
@@ -383,12 +370,6 @@ pub fn main_args(args: &[String]) -> isize {
     let css_file_extension = matches.opt_str("e").map(|s| PathBuf::from(&s));
     let cfgs = matches.opt_strs("cfg");
 
-    let render_type = if matches.opt_present("disable-commonmark") {
-        RenderType::Hoedown
-    } else {
-        RenderType::Pulldown
-    };
-
     if let Some(ref p) = css_file_extension {
         if !p.is_file() {
             writeln!(
@@ -425,8 +406,7 @@ pub fn main_args(args: &[String]) -> isize {
             &matches.opt_strs("html-before-content"),
             &matches.opt_strs("html-after-content"),
             &matches.opt_strs("markdown-before-content"),
-            &matches.opt_strs("markdown-after-content"),
-            render_type) {
+            &matches.opt_strs("markdown-after-content")) {
         Some(eh) => eh,
         None => return 3,
     };
@@ -440,22 +420,20 @@ pub fn main_args(args: &[String]) -> isize {
     match (should_test, markdown_input) {
         (true, true) => {
             return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot,
-                                  render_type, display_warnings, linker)
+                                  display_warnings, linker)
         }
         (true, false) => {
             return test::run(Path::new(input), cfgs, libs, externs, test_args, crate_name,
-                             maybe_sysroot, render_type, display_warnings, linker)
+                             maybe_sysroot, display_warnings, linker)
         }
         (false, true) => return markdown::render(Path::new(input),
                                                  output.unwrap_or(PathBuf::from("doc")),
                                                  &matches, &external_html,
-                                                 !matches.opt_present("markdown-no-toc"),
-                                                 render_type),
+                                                 !matches.opt_present("markdown-no-toc")),
         (false, false) => {}
     }
 
     let output_format = matches.opt_str("w");
-    let deny_render_differences = matches.opt_present("deny-render-differences");
     let res = acquire_input(PathBuf::from(input), externs, &matches, move |out| {
         let Output { krate, passes, renderinfo } = out;
         info!("going to format");
@@ -466,9 +444,7 @@ pub fn main_args(args: &[String]) -> isize {
                                   passes.into_iter().collect(),
                                   css_file_extension,
                                   renderinfo,
-                                  render_type,
                                   sort_modules_alphabetically,
-                                  deny_render_differences,
                                   themes)
                     .expect("failed to generate documentation");
                 0
@@ -559,11 +535,6 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
     let crate_name = matches.opt_str("crate-name");
     let crate_version = matches.opt_str("crate-version");
     let plugin_path = matches.opt_str("plugin-path");
-    let render_type = if matches.opt_present("disable-commonmark") {
-        RenderType::Hoedown
-    } else {
-        RenderType::Pulldown
-    };
 
     info!("starting to run rustc");
     let display_warnings = matches.opt_present("display-warnings");
@@ -578,7 +549,7 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
 
         let (mut krate, renderinfo) =
             core::run_core(paths, cfgs, externs, Input::File(cratefile), triple, maybe_sysroot,
-                           display_warnings, force_unstable_if_unmarked, render_type);
+                           display_warnings, force_unstable_if_unmarked);
 
         info!("finished with rustc");
 
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 9af2ebf0661da..0f107457d2bf8 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -17,20 +17,14 @@ use getopts;
 use testing;
 use rustc::session::search_paths::SearchPaths;
 use rustc::session::config::Externs;
-use syntax::codemap::{DUMMY_SP, FileName};
-
-use clean::Span;
+use syntax::codemap::DUMMY_SP;
 
 use externalfiles::{ExternalHtml, LoadStringError, load_string};
 
-use html_diff;
-
-use html::render::{render_text, reset_ids};
+use html::render::reset_ids;
 use html::escape::Escape;
-use html::render::render_difference;
 use html::markdown;
-use html::markdown::{Markdown, MarkdownWithToc, find_testable_code, old_find_testable_code};
-use html::markdown::RenderType;
+use html::markdown::{Markdown, MarkdownWithToc, find_testable_code};
 use test::{TestOptions, Collector};
 
 /// Separate any lines at the start of the file that begin with `# ` or `%`.
@@ -55,12 +49,7 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
 /// Render `input` (e.g. "foo.md") into an HTML file in `output`
 /// (e.g. output = "bar" => "bar/foo.html").
 pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches,
-              external_html: &ExternalHtml, include_toc: bool,
-              render_type: RenderType) -> isize {
-    // Span used for markdown hoedown/pulldown differences.
-    let mut span = Span::empty();
-    span.filename = FileName::Real(input.to_owned());
-
+              external_html: &ExternalHtml, include_toc: bool) -> isize {
     output.push(input.file_stem().unwrap());
     output.set_extension("html");
 
@@ -97,36 +86,12 @@ pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches,
 
     reset_ids(false);
 
-    let (hoedown_output, pulldown_output) = if include_toc {
-        // Save the state of USED_ID_MAP so it only gets updated once even
-        // though we're rendering twice.
-        render_text(|ty| format!("{}", MarkdownWithToc(text, ty)))
+    let text = if include_toc {
+        format!("{}", MarkdownWithToc(text))
     } else {
-        // Save the state of USED_ID_MAP so it only gets updated once even
-        // though we're rendering twice.
-        render_text(|ty| format!("{}", Markdown(text, &[], ty)))
+        format!("{}", Markdown(text, &[]))
     };
 
-    let mut differences = html_diff::get_differences(&pulldown_output, &hoedown_output);
-    differences.retain(|s| {
-        match *s {
-            html_diff::Difference::NodeText { ref elem_text,
-                                              ref opposite_elem_text,
-                                              .. }
-                if elem_text.split_whitespace().eq(opposite_elem_text.split_whitespace()) => {
-                    false
-            }
-            _ => true,
-        }
-    });
-
-    if !differences.is_empty() {
-        let mut intro_msg = false;
-        for diff in differences {
-            render_difference(&diff, &mut intro_msg, &span, text);
-        }
-    }
-
     let err = write!(
         &mut out,
         r#"<!DOCTYPE html>
@@ -158,7 +123,7 @@ pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches,
         css = css,
         in_header = external_html.in_header,
         before_content = external_html.before_content,
-        text = if render_type == RenderType::Pulldown { pulldown_output } else { hoedown_output },
+        text = text,
         after_content = external_html.after_content,
     );
 
@@ -174,7 +139,7 @@ pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches,
 /// Run any tests/code examples in the markdown file `input`.
 pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
             mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
-            render_type: RenderType, display_warnings: bool, linker: Option<PathBuf>) -> isize {
+            display_warnings: bool, linker: Option<PathBuf>) -> isize {
     let input_str = match load_string(input) {
         Ok(s) => s,
         Err(LoadStringError::ReadFail) => return 1,
@@ -186,13 +151,8 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
     let mut collector = Collector::new(input.to_owned(), cfgs, libs, externs,
                                        true, opts, maybe_sysroot, None,
                                        Some(PathBuf::from(input)),
-                                       render_type, linker);
-    if render_type == RenderType::Pulldown {
-        old_find_testable_code(&input_str, &mut collector, DUMMY_SP);
-        find_testable_code(&input_str, &mut collector, DUMMY_SP);
-    } else {
-        old_find_testable_code(&input_str, &mut collector, DUMMY_SP);
-    }
+                                       linker);
+    find_testable_code(&input_str, &mut collector, DUMMY_SP);
     test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&test_args, collector.tests,
                        testing::Options::new().display_output(display_warnings));
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 087d88419bc84..b49dd13adbc2e 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::collections::HashMap;
 use std::env;
 use std::ffi::OsString;
 use std::io::prelude::*;
@@ -41,7 +40,7 @@ use errors;
 use errors::emitter::ColorConfig;
 
 use clean::Attributes;
-use html::markdown::{self, RenderType};
+use html::markdown;
 
 #[derive(Clone, Default)]
 pub struct TestOptions {
@@ -56,7 +55,6 @@ pub fn run(input_path: &Path,
            mut test_args: Vec<String>,
            crate_name: Option<String>,
            maybe_sysroot: Option<PathBuf>,
-           render_type: RenderType,
            display_warnings: bool,
            linker: Option<PathBuf>)
            -> isize {
@@ -118,7 +116,6 @@ pub fn run(input_path: &Path,
                                        maybe_sysroot,
                                        Some(codemap),
                                        None,
-                                       render_type,
                                        linker);
 
     {
@@ -433,8 +430,6 @@ fn partition_source(s: &str) -> (String, String) {
 
 pub struct Collector {
     pub tests: Vec<testing::TestDescAndFn>,
-    // to be removed when hoedown will be definitely gone
-    pub old_tests: HashMap<String, Vec<String>>,
 
     // The name of the test displayed to the user, separated by `::`.
     //
@@ -468,8 +463,6 @@ pub struct Collector {
     position: Span,
     codemap: Option<Rc<CodeMap>>,
     filename: Option<PathBuf>,
-    // to be removed when hoedown will be removed as well
-    pub render_type: RenderType,
     linker: Option<PathBuf>,
 }
 
@@ -477,10 +470,9 @@ impl Collector {
     pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
                use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
                codemap: Option<Rc<CodeMap>>, filename: Option<PathBuf>,
-               render_type: RenderType, linker: Option<PathBuf>) -> Collector {
+               linker: Option<PathBuf>) -> Collector {
         Collector {
             tests: Vec::new(),
-            old_tests: HashMap::new(),
             names: Vec::new(),
             cfgs,
             libs,
@@ -492,7 +484,6 @@ impl Collector {
             position: DUMMY_SP,
             codemap,
             filename,
-            render_type,
             linker,
         }
     }
@@ -501,39 +492,11 @@ impl Collector {
         format!("{} - {} (line {})", filename, self.names.join("::"), line)
     }
 
-    // to be removed once hoedown is gone
-    fn generate_name_beginning(&self, filename: &FileName) -> String {
-        format!("{} - {} (line", filename, self.names.join("::"))
-    }
-
-    pub fn add_old_test(&mut self, test: String, filename: FileName) {
-        let name_beg = self.generate_name_beginning(&filename);
-        let entry = self.old_tests.entry(name_beg)
-                                  .or_insert(Vec::new());
-        entry.push(test.trim().to_owned());
-    }
-
     pub fn add_test(&mut self, test: String,
                     should_panic: bool, no_run: bool, should_ignore: bool,
                     as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
                     line: usize, filename: FileName, allow_fail: bool) {
         let name = self.generate_name(line, &filename);
-        // to be removed when hoedown is removed
-        if self.render_type == RenderType::Pulldown {
-            let name_beg = self.generate_name_beginning(&filename);
-            let mut found = false;
-            let test = test.trim().to_owned();
-            if let Some(entry) = self.old_tests.get_mut(&name_beg) {
-                found = entry.remove_item(&test).is_some();
-            }
-            if !found {
-                eprintln!("WARNING: {} Code block is not currently run as a test, but will \
-                           in future versions of rustdoc. Please ensure this code block is \
-                           a runnable test, or use the `ignore` directive.",
-                          name);
-                return
-            }
-        }
         let cfgs = self.cfgs.clone();
         let libs = self.libs.clone();
         let externs = self.externs.clone();
@@ -680,15 +643,8 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
         // the collapse-docs pass won't combine sugared/raw doc attributes, or included files with
         // anything else, this will combine them for us
         if let Some(doc) = attrs.collapsed_doc_value() {
-            if self.collector.render_type == RenderType::Pulldown {
-                markdown::old_find_testable_code(&doc, self.collector,
-                                                 attrs.span.unwrap_or(DUMMY_SP));
-                markdown::find_testable_code(&doc, self.collector,
-                                             attrs.span.unwrap_or(DUMMY_SP));
-            } else {
-                markdown::old_find_testable_code(&doc, self.collector,
-                                                 attrs.span.unwrap_or(DUMMY_SP));
-            }
+            markdown::find_testable_code(&doc, self.collector,
+                                         attrs.span.unwrap_or(DUMMY_SP));
         }
 
         nested(self);
diff --git a/src/rt/hoedown b/src/rt/hoedown
deleted file mode 160000
index da282f1bb7277..0000000000000
--- a/src/rt/hoedown
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit da282f1bb7277b4d30fa1599ee29ad8eb4dd2a92
diff --git a/src/test/rustdoc/link-title-escape.rs b/src/test/rustdoc/link-title-escape.rs
index eb53c3c2cb52d..e10ff1a991705 100644
--- a/src/test/rustdoc/link-title-escape.rs
+++ b/src/test/rustdoc/link-title-escape.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z unstable-options --disable-commonmark
-
 #![crate_name = "foo"]
 
 //! hello [foo]
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 8454e71fa3f9b..76f5f98358c9e 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -24,7 +24,7 @@ use std::path::PathBuf;
 
 use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
 
-use rustdoc::html::markdown::{Markdown, PLAYGROUND, RenderType};
+use rustdoc::html::markdown::{Markdown, PLAYGROUND};
 use rustc_serialize::json;
 
 enum OutputFormat {
@@ -100,7 +100,7 @@ impl Formatter for HTMLFormatter {
 
         // Description rendered as markdown.
         match info.description {
-            Some(ref desc) => write!(output, "{}", Markdown(desc, &[], RenderType::Hoedown))?,
+            Some(ref desc) => write!(output, "{}", Markdown(desc, &[]))?,
             None => write!(output, "<p>No description.</p>\n")?,
         }