about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-01-18 14:03:12 +0000
committerbors <bors@rust-lang.org>2018-01-18 14:03:12 +0000
commit3bd4af88bea2e6ecdd3455ed89b3ef1fc3500aa4 (patch)
tree7932af7a8bee193a20ff42ba160c1297e4aedfb4
parent44afd76788df1a63fcd3fe19815eb28dbe9c2bf7 (diff)
parent260653772a35d44ea474fc6d464432ac6f2a676f (diff)
downloadrust-3bd4af88bea2e6ecdd3455ed89b3ef1fc3500aa4.tar.gz
rust-3bd4af88bea2e6ecdd3455ed89b3ef1fc3500aa4.zip
Auto merge of #47528 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 6 pull requests

- Successful merges: #47250, #47313, #47398, #47468, #47471, #47520
- Failed merges:
-rw-r--r--src/bootstrap/builder.rs7
-rw-r--r--src/bootstrap/check.rs37
-rw-r--r--src/bootstrap/doc.rs4
-rw-r--r--src/librustc/traits/error_reporting.rs8
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs28
-rw-r--r--src/librustdoc/clean/inline.rs9
-rw-r--r--src/librustdoc/clean/mod.rs3
-rw-r--r--src/librustdoc/html/render.rs5
-rw-r--r--src/librustdoc/html/static/main.js82
-rw-r--r--src/librustdoc/lib.rs10
-rw-r--r--src/libstd/fs.rs16
-rw-r--r--src/test/rustdoc-js/basic.js25
-rw-r--r--src/test/rustdoc-js/enum-option.js17
-rw-r--r--src/test/rustdoc-js/fn-forget.js18
-rw-r--r--src/test/rustdoc-js/from_u.js22
-rw-r--r--src/test/rustdoc-js/macro-print.js20
-rw-r--r--src/test/rustdoc-js/string-from_ut.js21
-rw-r--r--src/test/rustdoc-js/struct-vec.js19
-rw-r--r--src/test/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs18
-rw-r--r--src/test/rustdoc/inline_cross/impl-inline-without-trait.rs22
-rw-r--r--src/test/ui/anonymous-higher-ranked-lifetime.stderr66
-rw-r--r--src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr18
-rw-r--r--src/test/ui/did_you_mean/recursion_limit.stderr6
-rw-r--r--src/test/ui/fmt/send-sync.stderr12
-rw-r--r--src/test/ui/generator/not-send-sync.stderr12
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.stderr12
-rw-r--r--src/test/ui/issue-24424.stderr6
-rw-r--r--src/test/ui/mismatched_types/E0631.stderr24
-rw-r--r--src/test/ui/mismatched_types/closure-arg-count.stderr6
-rw-r--r--src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr12
-rw-r--r--src/test/ui/mismatched_types/closure-mismatch.stderr12
-rw-r--r--src/test/ui/mismatched_types/fn-variance-1.stderr12
-rw-r--r--src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs4
-rw-r--r--src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr13
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.stderr18
-rw-r--r--src/test/ui/on-unimplemented/on-impl.stderr6
-rw-r--r--src/test/ui/on-unimplemented/on-trait.stderr12
-rw-r--r--src/test/ui/span/issue-29595.stderr6
-rw-r--r--src/test/ui/suggestions/fn-closure-mutable-capture.rs20
-rw-r--r--src/test/ui/suggestions/fn-closure-mutable-capture.stderr15
-rw-r--r--src/test/ui/suggestions/try-operator-on-main.stderr6
-rw-r--r--src/test/ui/type-annotation-needed.rs17
-rw-r--r--src/test/ui/type-annotation-needed.stderr14
-rw-r--r--src/test/ui/type-check/issue-40294.stderr6
-rw-r--r--src/tools/rustdoc-js/tester.js210
45 files changed, 821 insertions, 115 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 6e8c6f7f1db..7655097681b 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -254,7 +254,9 @@ impl<'a> Builder<'a> {
             Kind::Test => describe!(check::Tidy, check::Bootstrap, check::DefaultCompiletest,
                 check::HostCompiletest, check::Crate, check::CrateLibrustc, check::Rustdoc,
                 check::Linkcheck, check::Cargotest, check::Cargo, check::Rls, check::Docs,
-                check::ErrorIndex, check::Distcheck, check::Rustfmt, check::Miri, check::Clippy),
+                check::ErrorIndex, check::Distcheck, check::Rustfmt, check::Miri, check::Clippy,
+                check::RustdocJS),
+
             Kind::Bench => describe!(check::Crate, check::CrateLibrustc),
             Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
                 doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon,
@@ -443,7 +445,8 @@ impl<'a> Builder<'a> {
         let out_dir = self.stage_out(compiler, mode);
         cargo.env("CARGO_TARGET_DIR", out_dir)
              .arg(cmd)
-             .arg("--target").arg(target);
+             .arg("--target")
+             .arg(target);
 
         // If we were invoked from `make` then that's already got a jobserver
         // set up for us so no need to tell Cargo about jobs all over again.
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index ed110762cb3..78ad71172a8 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -424,6 +424,43 @@ fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString {
     env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")
 }
 
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct RustdocJS {
+    pub host: Interned<String>,
+    pub target: Interned<String>,
+}
+
+impl Step for RustdocJS {
+    type Output = ();
+    const DEFAULT: bool = true;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun) -> ShouldRun {
+        run.path("src/test/rustdoc-js")
+    }
+
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(RustdocJS {
+            host: run.host,
+            target: run.target,
+        });
+    }
+
+    fn run(self, builder: &Builder) {
+        if let Some(ref nodejs) = builder.config.nodejs {
+            let mut command = Command::new(nodejs);
+            command.args(&["src/tools/rustdoc-js/tester.js", &*self.host]);
+            builder.ensure(::doc::Std {
+                target: self.target,
+                stage: builder.top_stage,
+            });
+            builder.run(&mut command);
+        } else {
+            println!("No nodejs found, skipping \"src/test/rustdoc-js\" tests");
+        }
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Tidy {
     host: Interned<String>,
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 1a185889f43..9bf762a3b4b 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -419,8 +419,8 @@ impl Step for Standalone {
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Std {
-    stage: u32,
-    target: Interned<String>,
+    pub stage: u32,
+    pub target: Interned<String>,
 }
 
 impl Step for Std {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 54da23821f5..1aca687af2b 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1241,7 +1241,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             }
             ObligationCauseCode::ItemObligation(item_def_id) => {
                 let item_name = tcx.item_path_str(item_def_id);
-                err.note(&format!("required by `{}`", item_name));
+                let msg = format!("required by `{}`", item_name);
+                if let Some(sp) = tcx.hir.span_if_local(item_def_id) {
+                    let sp = tcx.sess.codemap().def_span(sp);
+                    err.span_note(sp, &msg);
+                } else {
+                    err.note(&msg);
+                }
             }
             ObligationCauseCode::ObjectCastObligation(object_ty) => {
                 err.note(&format!("required for the cast to the object type `{}`",
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 4529e4bab75..d003ef74f05 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -842,10 +842,32 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                         if let mc::NoteClosureEnv(upvar_id) = err.cmt.note {
                             let node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id);
                             let sp = self.tcx.hir.span(node_id);
-                            match self.tcx.sess.codemap().span_to_snippet(sp) {
-                                Ok(snippet) => {
+                            let fn_closure_msg = "`Fn` closures cannot capture their enclosing \
+                                                  environment for modifications";
+                            match (self.tcx.sess.codemap().span_to_snippet(sp), &err.cmt.cat) {
+                                (_, &Categorization::Upvar(mc::Upvar {
+                                    kind: ty::ClosureKind::Fn, ..
+                                })) => {
+                                    db.note(fn_closure_msg);
+                                    // we should point at the cause for this closure being
+                                    // identified as `Fn` (like in signature of method this
+                                    // closure was passed into)
+                                }
+                                (Ok(ref snippet), ref cat) => {
                                     let msg = &format!("consider making `{}` mutable", snippet);
-                                    db.span_suggestion(sp, msg, format!("mut {}", snippet));
+                                    let suggestion = format!("mut {}", snippet);
+
+                                    if let &Categorization::Deref(ref cmt, _) = cat {
+                                        if let Categorization::Upvar(mc::Upvar {
+                                            kind: ty::ClosureKind::Fn, ..
+                                        }) = cmt.cat {
+                                            db.note(fn_closure_msg);
+                                        } else {
+                                            db.span_suggestion(sp, msg, suggestion);
+                                        }
+                                    } else {
+                                        db.span_suggestion(sp, msg, suggestion);
+                                    }
                                 }
                                 _ => {
                                     db.span_help(sp, "consider making this binding mutable");
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index d284757df63..b8c34d78d30 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -328,6 +328,9 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
     if trait_.def_id() == tcx.lang_items().deref_trait() {
         super::build_deref_target_impls(cx, &trait_items, ret);
     }
+    if let Some(trait_did) = trait_.def_id() {
+        record_extern_trait(cx, trait_did);
+    }
 
     let provided = trait_.def_id().map(|did| {
         tcx.provided_trait_methods(did)
@@ -483,3 +486,9 @@ fn separate_supertrait_bounds(mut g: clean::Generics)
     });
     (g, ty_bounds)
 }
+
+pub fn record_extern_trait(cx: &DocContext, did: DefId) {
+    cx.external_traits.borrow_mut().entry(did).or_insert_with(|| {
+        build_external_trait(cx, did)
+    });
+}
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 271bc967bc9..cc75664cacb 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -3163,8 +3163,7 @@ fn register_def(cx: &DocContext, def: Def) -> DefId {
     if did.is_local() { return did }
     inline::record_extern_fqn(cx, did, kind);
     if let TypeKind::Trait = kind {
-        let t = inline::build_external_trait(cx, did);
-        cx.external_traits.borrow_mut().insert(did, t);
+        inline::record_extern_trait(cx, did);
     }
     did
 }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 2293e31b579..cfa09ea30a8 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -3277,8 +3277,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> {
         if let Some(impls) = c.impls.get(&did) {
             for i in impls {
                 let impl_ = i.inner_impl();
-                if impl_.trait_.def_id().and_then(|d| c.traits.get(&d))
-                                        .map_or(false, |t| t.is_spotlight) {
+                if impl_.trait_.def_id().map_or(false, |d| c.traits[&d].is_spotlight) {
                     if out.is_empty() {
                         out.push_str(
                             &format!("<h3 class=\"important\">Important traits for {}</h3>\
@@ -3444,7 +3443,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
     }
 
     let traits = &cache().traits;
-    let trait_ = i.trait_did().and_then(|did| traits.get(&did));
+    let trait_ = i.trait_did().map(|did| &traits[&did]);
 
     if !show_def_docs {
         write!(w, "<span class='docblock autohide'>")?;
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index b4dbd76d0b4..a9a5bd5de05 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -353,35 +353,33 @@
      * This code is an unmodified version of the code written by Marco de Wit
      * and was found at http://stackoverflow.com/a/18514751/745719
      */
-    var levenshtein = (function() {
-        var row2 = [];
-        return function(s1, s2) {
-            if (s1 === s2) {
-                return 0;
+    var levenshtein_row2 = [];
+    function levenshtein(s1, s2) {
+        if (s1 === s2) {
+            return 0;
+        }
+        var s1_len = s1.length, s2_len = s2.length;
+        if (s1_len && s2_len) {
+            var i1 = 0, i2 = 0, a, b, c, c2, row = levenshtein_row2;
+            while (i1 < s1_len) {
+                row[i1] = ++i1;
             }
-            var s1_len = s1.length, s2_len = s2.length;
-            if (s1_len && s2_len) {
-                var i1 = 0, i2 = 0, a, b, c, c2, row = row2;
-                while (i1 < s1_len) {
-                    row[i1] = ++i1;
-                }
-                while (i2 < s2_len) {
-                    c2 = s2.charCodeAt(i2);
-                    a = i2;
-                    ++i2;
-                    b = i2;
-                    for (i1 = 0; i1 < s1_len; ++i1) {
-                        c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0);
-                        a = row[i1];
-                        b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c);
-                        row[i1] = b;
-                    }
+            while (i2 < s2_len) {
+                c2 = s2.charCodeAt(i2);
+                a = i2;
+                ++i2;
+                b = i2;
+                for (i1 = 0; i1 < s1_len; ++i1) {
+                    c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0);
+                    a = row[i1];
+                    b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c);
+                    row[i1] = b;
                 }
-                return b;
             }
-            return s1_len + s2_len;
-        };
-    })();
+            return b;
+        }
+        return s1_len + s2_len;
+    }
 
     function initSearch(rawSearchIndex) {
         var currentResults, index, searchIndex;
@@ -400,12 +398,20 @@
         /**
          * Executes the query and builds an index of results
          * @param  {[Object]} query     [The user query]
-         * @param  {[type]} max         [The maximum results returned]
          * @param  {[type]} searchWords [The list of search words to query
          *                               against]
          * @return {[type]}             [A search index of results]
          */
-        function execQuery(query, max, searchWords) {
+        function execQuery(query, searchWords) {
+            function itemTypeFromName(typename) {
+                for (var i = 0; i < itemTypes.length; ++i) {
+                    if (itemTypes[i] === typename) {
+                        return i;
+                    }
+                }
+                return -1;
+            }
+
             var valLower = query.query.toLowerCase(),
                 val = valLower,
                 typeFilter = itemTypeFromName(query.type),
@@ -1021,9 +1027,8 @@
             return true;
         }
 
-        function getQuery() {
-            var matches, type, query, raw =
-                document.getElementsByClassName('search-input')[0].value;
+        function getQuery(raw) {
+            var matches, type, query;
             query = raw;
 
             matches = query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i);
@@ -1227,7 +1232,7 @@
         }
 
         function showResults(results) {
-            var output, query = getQuery();
+            var output, query = getQuery(document.getElementsByClassName('search-input')[0].value);
 
             currentResults = query.id;
             output = '<h1>Results for ' + escape(query.query) +
@@ -1271,7 +1276,7 @@
                 resultIndex;
             var params = getQueryStringParams();
 
-            query = getQuery();
+            query = getQuery(document.getElementsByClassName('search-input')[0].value);
             if (e) {
                 e.preventDefault();
             }
@@ -1293,19 +1298,10 @@
                 }
             }
 
-            results = execQuery(query, 20000, index);
+            results = execQuery(query, index);
             showResults(results);
         }
 
-        function itemTypeFromName(typename) {
-            for (var i = 0; i < itemTypes.length; ++i) {
-                if (itemTypes[i] === typename) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
         function buildIndex(rawSearchIndex) {
             searchIndex = [];
             var searchWords = [];
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 3b43eafb849..0b57d5d26ce 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -242,8 +242,8 @@ pub fn opts() -> Vec<RustcOptGroup> {
                       or `#![doc(html_playground_url=...)]`",
                      "URL")
         }),
-        unstable("enable-commonmark", |o| {
-            o.optflag("", "enable-commonmark", "to enable commonmark doc rendering/testing")
+        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")
@@ -347,10 +347,10 @@ 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("enable-commonmark") {
-        RenderType::Pulldown
-    } else {
+    let render_type = if matches.opt_present("disable-commonmark") {
         RenderType::Hoedown
+    } else {
+        RenderType::Pulldown
     };
 
     if let Some(ref p) = css_file_extension {
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 4e0ff450cab..d1f3ccbd2c6 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -211,12 +211,12 @@ pub struct DirBuilder {
     recursive: bool,
 }
 
-/// How large a buffer to pre-allocate before reading the entire file at `path`.
-fn initial_buffer_size<P: AsRef<Path>>(path: P) -> usize {
+/// How large a buffer to pre-allocate before reading the entire file.
+fn initial_buffer_size(file: &File) -> usize {
     // Allocate one extra byte so the buffer doesn't need to grow before the
     // final `read` call at the end of the file.  Don't worry about `usize`
     // overflow because reading will fail regardless in that case.
-    metadata(path).map(|m| m.len() as usize + 1).unwrap_or(0)
+    file.metadata().map(|m| m.len() as usize + 1).unwrap_or(0)
 }
 
 /// Read the entire contents of a file into a bytes vector.
@@ -254,8 +254,9 @@ fn initial_buffer_size<P: AsRef<Path>>(path: P) -> usize {
 /// ```
 #[unstable(feature = "fs_read_write", issue = "46588")]
 pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
-    let mut bytes = Vec::with_capacity(initial_buffer_size(&path));
-    File::open(path)?.read_to_end(&mut bytes)?;
+    let mut file = File::open(path)?;
+    let mut bytes = Vec::with_capacity(initial_buffer_size(&file));
+    file.read_to_end(&mut bytes)?;
     Ok(bytes)
 }
 
@@ -295,8 +296,9 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
 /// ```
 #[unstable(feature = "fs_read_write", issue = "46588")]
 pub fn read_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
-    let mut string = String::with_capacity(initial_buffer_size(&path));
-    File::open(path)?.read_to_string(&mut string)?;
+    let mut file = File::open(path)?;
+    let mut string = String::with_capacity(initial_buffer_size(&file));
+    file.read_to_string(&mut string)?;
     Ok(string)
 }
 
diff --git a/src/test/rustdoc-js/basic.js b/src/test/rustdoc-js/basic.js
new file mode 100644
index 00000000000..863437cac91
--- /dev/null
+++ b/src/test/rustdoc-js/basic.js
@@ -0,0 +1,25 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const QUERY = 'String';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std::string', 'name': 'String' },
+        { 'path': 'std::ffi', 'name': 'OsString' },
+        { 'path': 'std::ffi', 'name': 'CString' },
+    ],
+    'in_args': [
+        { 'path': 'std::str', 'name': 'eq' },
+    ],
+    'returned': [
+        { 'path': 'std::string::String', 'name': 'add' },
+    ],
+};
diff --git a/src/test/rustdoc-js/enum-option.js b/src/test/rustdoc-js/enum-option.js
new file mode 100644
index 00000000000..3dac983b11b
--- /dev/null
+++ b/src/test/rustdoc-js/enum-option.js
@@ -0,0 +1,17 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const QUERY = 'enum:Option';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std::option', 'name': 'Option' },
+    ],
+};
diff --git a/src/test/rustdoc-js/fn-forget.js b/src/test/rustdoc-js/fn-forget.js
new file mode 100644
index 00000000000..10310d5eaf7
--- /dev/null
+++ b/src/test/rustdoc-js/fn-forget.js
@@ -0,0 +1,18 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const QUERY = 'fn:forget';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std::mem', 'name': 'forget' },
+        { 'path': 'std::fmt', 'name': 'format' },
+    ],
+};
diff --git a/src/test/rustdoc-js/from_u.js b/src/test/rustdoc-js/from_u.js
new file mode 100644
index 00000000000..920620a9aee
--- /dev/null
+++ b/src/test/rustdoc-js/from_u.js
@@ -0,0 +1,22 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const QUERY = 'from_u';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std::char', 'name': 'from_u32' },
+        { 'path': 'std::str', 'name': 'from_utf8' },
+        { 'path': 'std::string::String', 'name': 'from_utf8' },
+        { 'path': 'std::boxed::Box', 'name': 'from_unique' },
+        { 'path': 'std::i32', 'name': 'from_unsigned' },
+        { 'path': 'std::i128', 'name': 'from_unsigned' },
+    ],
+};
diff --git a/src/test/rustdoc-js/macro-print.js b/src/test/rustdoc-js/macro-print.js
new file mode 100644
index 00000000000..811ba3474af
--- /dev/null
+++ b/src/test/rustdoc-js/macro-print.js
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const QUERY = 'macro:print';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std', 'name': 'print' },
+        { 'path': 'std', 'name': 'eprint' },
+        { 'path': 'std', 'name': 'println' },
+        { 'path': 'std', 'name': 'eprintln' },
+    ],
+};
diff --git a/src/test/rustdoc-js/string-from_ut.js b/src/test/rustdoc-js/string-from_ut.js
new file mode 100644
index 00000000000..3d08ee37366
--- /dev/null
+++ b/src/test/rustdoc-js/string-from_ut.js
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const QUERY = 'String::from_ut';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std::string::String', 'name': 'from_utf8' },
+        { 'path': 'std::string::String', 'name': 'from_utf8' },
+        { 'path': 'std::string::String', 'name': 'from_utf8_lossy' },
+        { 'path': 'std::string::String', 'name': 'from_utf16_lossy' },
+        { 'path': 'std::string::String', 'name': 'from_utf8_unchecked' },
+    ],
+};
diff --git a/src/test/rustdoc-js/struct-vec.js b/src/test/rustdoc-js/struct-vec.js
new file mode 100644
index 00000000000..a91bc2d0da2
--- /dev/null
+++ b/src/test/rustdoc-js/struct-vec.js
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const QUERY = 'struct:Vec';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std::vec', 'name': 'Vec' },
+        { 'path': 'std::collections', 'name': 'VecDeque' },
+        { 'path': 'alloc::raw_vec', 'name': 'RawVec' },
+    ],
+};
diff --git a/src/test/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs b/src/test/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs
new file mode 100644
index 00000000000..5d4adb28cd8
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs
@@ -0,0 +1,18 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait MyTrait {
+    /// docs for my_trait_method
+    fn my_trait_method() {}
+}
+
+pub struct MyStruct;
+
+impl MyTrait for MyStruct {}
diff --git a/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs b/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs
new file mode 100644
index 00000000000..ea97d9d6ac2
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:impl-inline-without-trait.rs
+// build-aux-docs
+// ignore-cross-compile
+
+#![crate_name = "foo"]
+
+extern crate impl_inline_without_trait;
+
+// @has 'foo/struct.MyStruct.html'
+// @has - '//*[@id="method.my_trait_method"]' 'fn my_trait_method()'
+// @has - '//*[@class="docblock"]' 'docs for my_trait_method'
+pub use impl_inline_without_trait::MyStruct;
diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
index e364a4d8b14..4bd3b684b7b 100644
--- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr
+++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
@@ -6,7 +6,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _`
    |
-   = note: required by `f1`
+note: required by `f1`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:26:1
+   |
+26 | fn f1<F>(_: F) where F: Fn(&(), &()) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:13:5
@@ -16,7 +20,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _`
    |
-   = note: required by `f2`
+note: required by `f2`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1
+   |
+27 | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
@@ -26,7 +34,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r> fn(&(), &'r ()) -> _`
    |
-   = note: required by `f3`
+note: required by `f3`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1
+   |
+28 | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:15:5
@@ -36,7 +48,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _`
    |
-   = note: required by `f4`
+note: required by `f4`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1
+   |
+29 | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
@@ -46,7 +62,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r> fn(&'r (), &'r ()) -> _`
    |
-   = note: required by `f5`
+note: required by `f5`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1
+   |
+30 | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:17:5
@@ -56,7 +76,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>) -> _`
    |
-   = note: required by `g1`
+note: required by `g1`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:33:1
+   |
+33 | fn g1<F>(_: F) where F: Fn(&(), Box<Fn(&())>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
@@ -66,7 +90,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _`
    |
-   = note: required by `g2`
+note: required by `g2`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1
+   |
+34 | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:19:5
@@ -76,7 +104,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'s> fn(&'s (), std::boxed::Box<for<'r> std::ops::Fn(&'r ()) + 'static>) -> _`
    |
-   = note: required by `g3`
+note: required by `g3`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1
+   |
+35 | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<Fn(&())>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
@@ -86,7 +118,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _`
    |
-   = note: required by `g4`
+note: required by `g4`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1
+   |
+36 | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:21:5
@@ -96,7 +132,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<for<'t0> std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
    |
-   = note: required by `h1`
+note: required by `h1`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:39:1
+   |
+39 | fn h1<F>(_: F) where F: Fn(&(), Box<Fn(&())>, &(), fn(&(), &())) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
@@ -106,7 +146,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
    |
-   = note: required by `h2`
+note: required by `h2`
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1
+   |
+40 | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<Fn(&())>, &'t0 (), fn(&(), &())) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index d5c4add34b5..7ca3e8728fd 100644
--- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -10,7 +10,11 @@ error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied
              <i8 as Foo<u32>>
              <i8 as Foo<u64>>
              <i8 as Foo<bool>>
-   = note: required by `Foo::bar`
+note: required by `Foo::bar`
+  --> $DIR/issue-39802-show-5-trait-impls.rs:12:5
+   |
+12 |     fn bar(&self){}
+   |     ^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:35:5
@@ -23,7 +27,11 @@ error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
              <u8 as Foo<u32>>
              <u8 as Foo<u64>>
              <u8 as Foo<bool>>
-   = note: required by `Foo::bar`
+note: required by `Foo::bar`
+  --> $DIR/issue-39802-show-5-trait-impls.rs:12:5
+   |
+12 |     fn bar(&self){}
+   |     ^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:36:5
@@ -37,7 +45,11 @@ error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
              <bool as Foo<u32>>
              <bool as Foo<u64>>
            and 2 others
-   = note: required by `Foo::bar`
+note: required by `Foo::bar`
+  --> $DIR/issue-39802-show-5-trait-impls.rs:12:5
+   |
+12 |     fn bar(&self){}
+   |     ^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr
index 7fac604ba49..2bc7e9e46e7 100644
--- a/src/test/ui/did_you_mean/recursion_limit.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit.stderr
@@ -15,7 +15,11 @@ error[E0275]: overflow evaluating the requirement `K: std::marker::Send`
    = note: required because it appears within the type `C`
    = note: required because it appears within the type `B`
    = note: required because it appears within the type `A`
-   = note: required by `is_send`
+note: required by `is_send`
+  --> $DIR/recursion_limit.rs:41:1
+   |
+41 | fn is_send<T:Send>() { }
+   | ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr
index 9e0e563c35f..4ec5c9ebd27 100644
--- a/src/test/ui/fmt/send-sync.stderr
+++ b/src/test/ui/fmt/send-sync.stderr
@@ -12,7 +12,11 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync`
    = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]`
    = note: required because it appears within the type `std::fmt::Arguments<'_>`
-   = note: required by `send`
+note: required by `send`
+  --> $DIR/send-sync.rs:11:1
+   |
+11 | fn send<T: Send>(_: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>`
   --> $DIR/send-sync.rs:19:5
@@ -28,7 +32,11 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync`
    = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]`
    = note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]`
    = note: required because it appears within the type `std::fmt::Arguments<'_>`
-   = note: required by `sync`
+note: required by `sync`
+  --> $DIR/send-sync.rs:12:1
+   |
+12 | fn sync<T: Sync>(_: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index a1f110accc1..d30255335a6 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -7,7 +7,11 @@ error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not s
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::Cell<i32>`
    = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:26:17: 30:6 a:&std::cell::Cell<i32> _]`
-   = note: required by `main::assert_send`
+note: required by `main::assert_send`
+  --> $DIR/not-send-sync.rs:17:5
+   |
+17 |     fn assert_send<T: Send>(_: T) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 (std::cell::Cell<i32>, ())]`
   --> $DIR/not-send-sync.rs:19:5
@@ -18,7 +22,11 @@ error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not s
    = help: within `[generator@$DIR/not-send-sync.rs:19:17: 23:6 (std::cell::Cell<i32>, ())]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
    = note: required because it appears within the type `(std::cell::Cell<i32>, ())`
    = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:19:17: 23:6 (std::cell::Cell<i32>, ())]`
-   = note: required by `main::assert_sync`
+note: required by `main::assert_sync`
+  --> $DIR/not-send-sync.rs:16:5
+   |
+16 |     fn assert_sync<T: Sync>(_: T) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index ffd6a3fe4ff..838a3002e3a 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -7,7 +7,11 @@ error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::S
    = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
    = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:21:5: 21:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
    = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
-   = note: required by `send`
+note: required by `send`
+  --> $DIR/auto-trait-leak.rs:24:1
+   |
+24 | fn send<T: Send>(_: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
   --> $DIR/auto-trait-leak.rs:30:5
@@ -18,7 +22,11 @@ error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::S
    = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
    = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:38:5: 38:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
    = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
-   = note: required by `send`
+note: required by `send`
+  --> $DIR/auto-trait-leak.rs:24:1
+   |
+24 | fn send<T: Send>(_: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0391]: unsupported cyclic reference between types/traits detected
   --> $DIR/auto-trait-leak.rs:44:1
diff --git a/src/test/ui/issue-24424.stderr b/src/test/ui/issue-24424.stderr
index acdf348791b..55af26dd91e 100644
--- a/src/test/ui/issue-24424.stderr
+++ b/src/test/ui/issue-24424.stderr
@@ -4,7 +4,11 @@ error[E0283]: type annotations required: cannot resolve `T0: Trait0<'l0>`
 14 | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: required by `Trait0`
+note: required by `Trait0`
+  --> $DIR/issue-24424.rs:12:1
+   |
+12 | trait Trait0<'l0>  {}
+   | ^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr
index 442900e0a83..53f2f54325d 100644
--- a/src/test/ui/mismatched_types/E0631.stderr
+++ b/src/test/ui/mismatched_types/E0631.stderr
@@ -6,7 +6,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `fn(usize) -> _`
    |
-   = note: required by `foo`
+note: required by `foo`
+  --> $DIR/E0631.rs:13:1
+   |
+13 | fn foo<F: Fn(usize)>(_: F) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/E0631.rs:18:5
@@ -16,7 +20,11 @@ error[E0631]: type mismatch in closure arguments
    |     |
    |     expected signature of `fn(usize) -> _`
    |
-   = note: required by `bar`
+note: required by `bar`
+  --> $DIR/E0631.rs:14:1
+   |
+14 | fn bar<F: Fn<usize>>(_: F) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:19:5
@@ -27,7 +35,11 @@ error[E0631]: type mismatch in function arguments
 19 |     foo(f); //~ ERROR type mismatch
    |     ^^^ expected signature of `fn(usize) -> _`
    |
-   = note: required by `foo`
+note: required by `foo`
+  --> $DIR/E0631.rs:13:1
+   |
+13 | fn foo<F: Fn(usize)>(_: F) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:20:5
@@ -38,7 +50,11 @@ error[E0631]: type mismatch in function arguments
 20 |     bar(f); //~ ERROR type mismatch
    |     ^^^ expected signature of `fn(usize) -> _`
    |
-   = note: required by `bar`
+note: required by `bar`
+  --> $DIR/E0631.rs:14:1
+   |
+14 | fn bar<F: Fn<usize>>(_: F) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index 216f39bac54..ba25d67d76e 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -30,7 +30,11 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
    |     |
    |     expected closure that takes 1 argument
    |
-   = note: required by `f`
+note: required by `f`
+  --> $DIR/closure-arg-count.rs:13:1
+   |
+13 | fn f<F: Fn<usize>>(_: F) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments
   --> $DIR/closure-arg-count.rs:24:53
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
index 77d3a332767..dfd02fe23b6 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -31,7 +31,11 @@ error[E0631]: type mismatch in function arguments
    |     expected signature of `for<'r> fn(*mut &'r u32) -> _`
    |     found signature of `fn(*mut &'a u32) -> _`
    |
-   = note: required by `baz`
+note: required by `baz`
+  --> $DIR/closure-arg-type-mismatch.rs:18:1
+   |
+18 | fn baz<F: Fn(*mut &u32)>(_: F) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::FnOnce<(*mut &'r u32,)>>::Output == ()`
   --> $DIR/closure-arg-type-mismatch.rs:20:5
@@ -39,7 +43,11 @@ error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::Fn
 20 |     baz(f); //~ ERROR type mismatch
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
    |
-   = note: required by `baz`
+note: required by `baz`
+  --> $DIR/closure-arg-type-mismatch.rs:18:1
+   |
+18 | fn baz<F: Fn(*mut &u32)>(_: F) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr
index 99767ba1afa..01de7e07495 100644
--- a/src/test/ui/mismatched_types/closure-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-mismatch.stderr
@@ -5,7 +5,11 @@ error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.r
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
    |
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]`
-   = note: required by `baz`
+note: required by `baz`
+  --> $DIR/closure-mismatch.rs:15:1
+   |
+15 | fn baz<T: Foo>(_: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/closure-mismatch.rs:18:5
@@ -16,7 +20,11 @@ error[E0631]: type mismatch in closure arguments
    |     expected signature of `for<'r> fn(&'r ()) -> _`
    |
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]`
-   = note: required by `baz`
+note: required by `baz`
+  --> $DIR/closure-mismatch.rs:15:1
+   |
+15 | fn baz<T: Foo>(_: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr
index 2a27ffd1062..64c260c30ed 100644
--- a/src/test/ui/mismatched_types/fn-variance-1.stderr
+++ b/src/test/ui/mismatched_types/fn-variance-1.stderr
@@ -7,7 +7,11 @@ error[E0631]: type mismatch in function arguments
 21 |     apply(&3, takes_mut);
    |     ^^^^^ expected signature of `fn(&{integer}) -> _`
    |
-   = note: required by `apply`
+note: required by `apply`
+  --> $DIR/fn-variance-1.rs:15:1
+   |
+15 | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/fn-variance-1.rs:25:5
@@ -18,7 +22,11 @@ error[E0631]: type mismatch in function arguments
 25 |     apply(&mut 3, takes_imm);
    |     ^^^^^ expected signature of `fn(&mut {integer}) -> _`
    |
-   = note: required by `apply`
+note: required by `apply`
+  --> $DIR/fn-variance-1.rs:15:1
+   |
+15 | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
index 10f4b3229f0..f2237e495a0 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
@@ -15,13 +15,15 @@ use std::ops::FnMut;
 fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
 
 fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
+//~^ NOTE required by `call_it`
     f(2, y)
 }
 
 pub fn main() {
     let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
+    //~^ NOTE found signature of `fn(usize, isize) -> _`
     let z = call_it(3, f);
     //~^ ERROR type mismatch
-    //~| required by `call_it`
+    //~| NOTE expected signature of `fn(isize, isize) -> _`
     println!("{}", z);
 }
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
index 8539c8818c0..9c9bbd19c75 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
@@ -1,12 +1,17 @@
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/unboxed-closures-vtable-mismatch.rs:23:13
+  --> $DIR/unboxed-closures-vtable-mismatch.rs:25:13
    |
-22 |     let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
+23 |     let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
    |                       ----------------------------- found signature of `fn(usize, isize) -> _`
-23 |     let z = call_it(3, f);
+24 |     //~^ NOTE found signature of `fn(usize, isize) -> _`
+25 |     let z = call_it(3, f);
    |             ^^^^^^^ expected signature of `fn(isize, isize) -> _`
    |
-   = note: required by `call_it`
+note: required by `call_it`
+  --> $DIR/unboxed-closures-vtable-mismatch.rs:17:1
+   |
+17 | fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr
index 1f71be446ef..cfac3981be2 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.stderr
+++ b/src/test/ui/on-unimplemented/multiple-impls.stderr
@@ -5,7 +5,11 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
    |     ^^^^^^^^^^^^ trait message
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
-   = note: required by `Index::index`
+note: required by `Index::index`
+  --> $DIR/multiple-impls.rs:22:5
+   |
+22 |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:43:5
@@ -22,7 +26,11 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
    |     ^^^^^^^^^^^^ on impl for Foo
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
-   = note: required by `Index::index`
+note: required by `Index::index`
+  --> $DIR/multiple-impls.rs:22:5
+   |
+22 |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:46:5
@@ -39,7 +47,11 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
    |     ^^^^^^^^^^^^ on impl for Bar
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
-   = note: required by `Index::index`
+note: required by `Index::index`
+  --> $DIR/multiple-impls.rs:22:5
+   |
+22 |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:49:5
diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr
index c8c06bf44fd..ed2da68f081 100644
--- a/src/test/ui/on-unimplemented/on-impl.stderr
+++ b/src/test/ui/on-unimplemented/on-impl.stderr
@@ -5,7 +5,11 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
    |     ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
-   = note: required by `Index::index`
+note: required by `Index::index`
+  --> $DIR/on-impl.rs:19:5
+   |
+19 |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:32:5
diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr
index cde56022fae..028200a5558 100644
--- a/src/test/ui/on-unimplemented/on-trait.stderr
+++ b/src/test/ui/on-unimplemented/on-trait.stderr
@@ -5,7 +5,11 @@ error[E0277]: the trait bound `std::option::Option<std::vec::Vec<u8>>: MyFromIte
    |                              ^^^^^^^ a collection of type `std::option::Option<std::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
    |
    = help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option<std::vec::Vec<u8>>`
-   = note: required by `collect`
+note: required by `collect`
+  --> $DIR/on-trait.rs:31:1
+   |
+31 | fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not satisfied
   --> $DIR/on-trait.rs:40:21
@@ -14,7 +18,11 @@ error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not
    |                     ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo`
    |
    = help: the trait `Bar::Foo<u8, _, u32>` is not implemented for `std::string::String`
-   = note: required by `foobar`
+note: required by `foobar`
+  --> $DIR/on-trait.rs:21:1
+   |
+21 | fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr
index 81ba0057d71..9046b90f0e9 100644
--- a/src/test/ui/span/issue-29595.stderr
+++ b/src/test/ui/span/issue-29595.stderr
@@ -4,7 +4,11 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied
 17 |     let a: u8 = Tr::C; //~ ERROR the trait bound `u8: Tr` is not satisfied
    |                 ^^^^^ the trait `Tr` is not implemented for `u8`
    |
-   = note: required by `Tr::C`
+note: required by `Tr::C`
+  --> $DIR/issue-29595.rs:13:5
+   |
+13 |     const C: Self;
+   |     ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/fn-closure-mutable-capture.rs b/src/test/ui/suggestions/fn-closure-mutable-capture.rs
new file mode 100644
index 00000000000..385efebd590
--- /dev/null
+++ b/src/test/ui/suggestions/fn-closure-mutable-capture.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn bar<F: Fn()>(_f: F) {}
+
+pub fn foo() {
+    let mut x = 0;
+    bar(move || x = 1);
+    //~^ ERROR cannot assign to captured outer variable in an `Fn` closure
+    //~| NOTE `Fn` closures cannot capture their enclosing environment for modifications
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/fn-closure-mutable-capture.stderr b/src/test/ui/suggestions/fn-closure-mutable-capture.stderr
new file mode 100644
index 00000000000..6c79e447a3c
--- /dev/null
+++ b/src/test/ui/suggestions/fn-closure-mutable-capture.stderr
@@ -0,0 +1,15 @@
+error[E0594]: cannot assign to captured outer variable in an `Fn` closure
+  --> $DIR/fn-closure-mutable-capture.rs:15:17
+   |
+15 |     bar(move || x = 1);
+   |                 ^^^^^
+   |
+   = note: `Fn` closures cannot capture their enclosing environment for modifications
+help: consider changing this closure to take self by mutable reference
+  --> $DIR/fn-closure-mutable-capture.rs:15:9
+   |
+15 |     bar(move || x = 1);
+   |         ^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/try-operator-on-main.stderr b/src/test/ui/suggestions/try-operator-on-main.stderr
index beb627bda6b..3b32b4a9eb7 100644
--- a/src/test/ui/suggestions/try-operator-on-main.stderr
+++ b/src/test/ui/suggestions/try-operator-on-main.stderr
@@ -28,7 +28,11 @@ error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
 25 |     try_trait_generic::<()>(); //~ ERROR the trait bound
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()`
    |
-   = note: required by `try_trait_generic`
+note: required by `try_trait_generic`
+  --> $DIR/try-operator-on-main.rs:30:1
+   |
+30 | fn try_trait_generic<T: Try>() -> T {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
   --> $DIR/try-operator-on-main.rs:32:5
diff --git a/src/test/ui/type-annotation-needed.rs b/src/test/ui/type-annotation-needed.rs
new file mode 100644
index 00000000000..3ed6e5daf00
--- /dev/null
+++ b/src/test/ui/type-annotation-needed.rs
@@ -0,0 +1,17 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo<T: Into<String>>(x: i32) {}
+//~^ NOTE required by
+
+fn main() {
+    foo(42);
+    //~^ ERROR type annotations required
+}
diff --git a/src/test/ui/type-annotation-needed.stderr b/src/test/ui/type-annotation-needed.stderr
new file mode 100644
index 00000000000..7d49afbaff8
--- /dev/null
+++ b/src/test/ui/type-annotation-needed.stderr
@@ -0,0 +1,14 @@
+error[E0283]: type annotations required: cannot resolve `_: std::convert::Into<std::string::String>`
+  --> $DIR/type-annotation-needed.rs:15:5
+   |
+15 |     foo(42);
+   |     ^^^
+   |
+note: required by `foo`
+  --> $DIR/type-annotation-needed.rs:11:1
+   |
+11 | fn foo<T: Into<String>>(x: i32) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-check/issue-40294.stderr b/src/test/ui/type-check/issue-40294.stderr
index 2ca97aa3ef0..cf270afdeb1 100644
--- a/src/test/ui/type-check/issue-40294.stderr
+++ b/src/test/ui/type-check/issue-40294.stderr
@@ -10,7 +10,11 @@ error[E0283]: type annotations required: cannot resolve `&'a T: Foo`
 21 | | }
    | |_^
    |
-   = note: required by `Foo`
+note: required by `Foo`
+  --> $DIR/issue-40294.rs:11:1
+   |
+11 | trait Foo: Sized {
+   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
new file mode 100644
index 00000000000..7c9ee2a4943
--- /dev/null
+++ b/src/tools/rustdoc-js/tester.js
@@ -0,0 +1,210 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const fs = require('fs');
+
+const TEST_FOLDER = 'src/test/rustdoc-js/';
+
+// Stupid function extractor based on indent.
+function extractFunction(content, functionName) {
+    var x = content.split('\n');
+    var in_func = false;
+    var indent = 0;
+    var lines = [];
+
+    for (var i = 0; i < x.length; ++i) {
+        if (in_func === false) {
+            var splitter = "function " + functionName + "(";
+            if (x[i].trim().startsWith(splitter)) {
+                in_func = true;
+                indent = x[i].split(splitter)[0].length;
+                lines.push(x[i]);
+            }
+        } else {
+            lines.push(x[i]);
+            if (x[i].trim() === "}" && x[i].split("}")[0].length === indent) {
+                return lines.join("\n");
+            }
+        }
+    }
+    return null;
+}
+
+// Stupid function extractor for array.
+function extractArrayVariable(content, arrayName) {
+    var x = content.split('\n');
+    var found_var = false;
+    var lines = [];
+
+    for (var i = 0; i < x.length; ++i) {
+        if (found_var === false) {
+            var splitter = "var " + arrayName + " = [";
+            if (x[i].trim().startsWith(splitter)) {
+                found_var = true;
+                i -= 1;
+            }
+        } else {
+            lines.push(x[i]);
+            if (x[i].endsWith('];')) {
+                return lines.join("\n");
+            }
+        }
+    }
+    return null;
+}
+
+// Stupid function extractor for variable.
+function extractVariable(content, varName) {
+    var x = content.split('\n');
+    var found_var = false;
+    var lines = [];
+
+    for (var i = 0; i < x.length; ++i) {
+        if (found_var === false) {
+            var splitter = "var " + varName + " = ";
+            if (x[i].trim().startsWith(splitter)) {
+                found_var = true;
+                i -= 1;
+            }
+        } else {
+            lines.push(x[i]);
+            if (x[i].endsWith(';')) {
+                return lines.join("\n");
+            }
+        }
+    }
+    return null;
+}
+
+function loadContent(content) {
+    var Module = module.constructor;
+    var m = new Module();
+    m._compile(content, "tmp.js");
+    return m.exports;
+}
+
+function readFile(filePath) {
+    return fs.readFileSync(filePath, 'utf8');
+}
+
+function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) {
+    var content = '';
+    for (var i = 0; i < thingsToLoad.length; ++i) {
+        var tmp = funcToCall(fileContent, thingsToLoad[i]);
+        if (tmp === null) {
+            console.error('enable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
+            process.exit(1);
+        }
+        content += tmp;
+        content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';';
+    }
+    return content;
+}
+
+function lookForEntry(entry, data) {
+    for (var i = 0; i < data.length; ++i) {
+        var allGood = true;
+        for (var key in entry) {
+            if (!entry.hasOwnProperty(key)) {
+                continue;
+            }
+            var value = data[i][key];
+            // To make our life easier, if there is a "parent" type, we add it to the path.
+            if (key === 'path' && data[i]['parent'] !== undefined) {
+                if (value.length > 0) {
+                    value += '::' + data[i]['parent']['name'];
+                } else {
+                    value = data[i]['parent']['name'];
+                }
+            }
+            if (value !== entry[key]) {
+                allGood = false;
+                break;
+            }
+        }
+        if (allGood === true) {
+            return true;
+        }
+    }
+    return false;
+}
+
+function main(argv) {
+    if (argv.length !== 3) {
+        console.error("Expected toolchain to check as argument (for example 'x86_64-apple-darwin'");
+        return 1;
+    }
+    var toolchain = argv[2];
+
+    var mainJs = readFile("build/" + toolchain + "/doc/main.js");
+    var searchIndex = readFile("build/" + toolchain + "/doc/search-index.js").split("\n");
+    if (searchIndex[searchIndex.length - 1].length === 0) {
+        searchIndex.pop();
+    }
+    searchIndex.pop();
+    searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;');
+    finalJS = "";
+
+    var arraysToLoad = ["itemTypes"];
+    var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "TY_PRIMITIVE", "levenshtein_row2"];
+    // execQuery first parameter is built in getQuery (which takes in the search input).
+    // execQuery last parameter is built in buildIndex.
+    // buildIndex requires the hashmap from search-index.
+    var functionsToLoad = ["levenshtein", "validateResult", "getQuery", "buildIndex", "execQuery"];
+
+    finalJS += 'window = { "currentCrate": "std" };\n';
+    finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
+    finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);
+    finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs);
+
+    var loaded = loadContent(finalJS);
+    var index = loaded.buildIndex(searchIndex.searchIndex);
+
+    var errors = 0;
+
+    fs.readdirSync(TEST_FOLDER).forEach(function(file) {
+        var loadedFile = loadContent(readFile(TEST_FOLDER + file) +
+                               'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
+        const expected = loadedFile.EXPECTED;
+        const query = loadedFile.QUERY;
+        var results = loaded.execQuery(loaded.getQuery(query), index);
+        process.stdout.write('Checking "' + file + '" ... ');
+        var error_text = [];
+        for (var key in expected) {
+            if (!expected.hasOwnProperty(key)) {
+                continue;
+            }
+            if (!results.hasOwnProperty(key)) {
+                error_text.push('==> Unknown key "' + key + '"');
+                break;
+            }
+            var entry = expected[key];
+            var found = false;
+            for (var i = 0; i < entry.length; ++i) {
+                if (lookForEntry(entry[i], results[key]) === true) {
+                    found = true;
+                } else {
+                    error_text.push("==> Result not found in '" + key + "': '" +
+                                    JSON.stringify(entry[i]) + "'");
+                }
+            }
+        }
+        if (error_text.length !== 0) {
+            errors += 1;
+            console.error("FAILED");
+            console.error(error_text.join("\n"));
+        } else {
+            console.log("OK");
+        }
+    });
+    return errors;
+}
+
+process.exit(main(process.argv));