about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-09-22 02:44:28 +0000
committerbors <bors@rust-lang.org>2019-09-22 02:44:28 +0000
commitef906d0e3c50ba0833c5a135d705ab4f6bd93aea (patch)
tree3cb11a98eae84b5d69bf515178f96a999276ed76
parented8b708c1a6bf6d94f860eeb6a6b0b442c380d7f (diff)
parentf0e69ffb8d4385aa7daf24e2cc5088e0e5dd4db0 (diff)
downloadrust-ef906d0e3c50ba0833c5a135d705ab4f6bd93aea.tar.gz
rust-ef906d0e3c50ba0833c5a135d705ab4f6bd93aea.zip
Auto merge of #64666 - Centril:rollup-tp98vlr, r=Centril
Rollup of 9 pull requests

Successful merges:

 - #63907 (Add explanation to type mismatch involving type params and assoc types)
 - #64615 (rustbuild: Turn down compression on exe installers)
 - #64617 (rustbuild: Turn down compression on msi installers)
 - #64618 (rustbuild: Improve output of `dist` step)
 - #64619 (Fixes #63962. Hint about missing tuple parentheses in patterns)
 - #64634 (Update to LLVM 9.0.0)
 - #64635 (Allow using fn pointers in const fn with unleash miri)
 - #64660 (unify errors for tuple/struct variants)
 - #64664 (fully remove AstBuilder)

Failed merges:

r? @ghost
-rw-r--r--.gitmodules2
-rw-r--r--src/bootstrap/dist.rs66
-rw-r--r--src/etc/installer/exe/rust.iss6
-rw-r--r--src/etc/installer/msi/rust.wxs2
-rw-r--r--src/librustc/traits/mod.rs10
-rw-r--r--src/librustc/traits/util.rs27
-rw-r--r--src/librustc/ty/error.rs96
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs11
-rw-r--r--src/librustc_resolve/late/diagnostics.rs6
-rw-r--r--src/librustc_typeck/check/pat.rs41
-rw-r--r--src/libsyntax/ext/build.rs3
m---------src/llvm-project0
-rw-r--r--src/test/ui/associated-const/associated-const-generic-obligations.stderr2
-rw-r--r--src/test/ui/associated-types/associated-types-eq-3.stderr2
-rw-r--r--src/test/ui/associated-types/associated-types-issue-20346.stderr2
-rw-r--r--src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr4
-rw-r--r--src/test/ui/compare-method/reordered-type-param.stderr2
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr.rs37
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr.stderr152
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr_fail.rs13
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs26
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr71
-rw-r--r--src/test/ui/empty/empty-struct-tuple-pat.stderr7
-rw-r--r--src/test/ui/error-codes/E0023.rs2
-rw-r--r--src/test/ui/error-codes/E0023.stderr21
-rw-r--r--src/test/ui/hrtb/issue-62203-hrtb-ice.stderr2
-rw-r--r--src/test/ui/impl-trait/bound-normalization-fail.stderr4
-rw-r--r--src/test/ui/impl-trait/equality2.stderr2
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr2
-rw-r--r--src/test/ui/impl-trait/universal-mismatched-type.stderr2
-rw-r--r--src/test/ui/impl-trait/universal-two-impl-traits.stderr2
-rw-r--r--src/test/ui/issues/issue-13853.stderr2
-rw-r--r--src/test/ui/issues/issue-20225.stderr6
-rw-r--r--src/test/ui/issues/issue-24204.stderr1
-rw-r--r--src/test/ui/issues/issue-2951.stderr2
-rw-r--r--src/test/ui/issues/issue-32004.stderr5
-rw-r--r--src/test/ui/issues/issue-32323.stderr2
-rw-r--r--src/test/ui/issues/issue-63983.rs15
-rw-r--r--src/test/ui/issues/issue-63983.stderr15
-rw-r--r--src/test/ui/mismatched_types/issue-35030.stderr2
-rw-r--r--src/test/ui/specialization/specialization-default-projection.stderr4
-rw-r--r--src/test/ui/specialization/specialization-default-types.stderr4
-rw-r--r--src/test/ui/structs/struct-path-self-type-mismatch.stderr4
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr12
-rw-r--r--src/test/ui/type/type-parameter-names.stderr2
-rw-r--r--src/test/ui/type/type-params-in-different-spaces-1.stderr2
-rw-r--r--src/test/ui/type/type-params-in-different-spaces-3.stderr2
47 files changed, 637 insertions, 68 deletions
diff --git a/.gitmodules b/.gitmodules
index f64e21c5af0..3ff5af78097 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -43,7 +43,7 @@
 [submodule "src/llvm-project"]
 	path = src/llvm-project
 	url = https://github.com/rust-lang/llvm-project.git
-	branch = rustc/9.0-2019-07-12
+	branch = rustc/9.0-2019-09-19
 [submodule "src/doc/embedded-book"]
 	path = src/doc/embedded-book
 	url = https://github.com/rust-embedded/book.git
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index e27a6bf7da0..d9dff77a30e 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -18,7 +18,7 @@ use build_helper::{output, t};
 
 use crate::{Compiler, Mode, LLVM_TOOLS};
 use crate::channel;
-use crate::util::{is_dylib, exe};
+use crate::util::{is_dylib, exe, timeit};
 use crate::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::compile;
 use crate::tool::{self, Tool};
@@ -91,14 +91,15 @@ impl Step for Docs {
 
         let name = pkgname(builder, "rust-docs");
 
-        builder.info(&format!("Dist docs ({})", host));
         if !builder.config.docs {
-            builder.info("\tskipping - docs disabled");
             return distdir(builder).join(format!("{}-{}.tar.gz", name, host));
         }
 
         builder.default_doc(None);
 
+        builder.info(&format!("Dist docs ({})", host));
+        let _time = timeit(builder);
+
         let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
         let _ = fs::remove_dir_all(&image);
 
@@ -151,9 +152,7 @@ impl Step for RustcDocs {
 
         let name = pkgname(builder, "rustc-docs");
 
-        builder.info(&format!("Dist compiler docs ({})", host));
         if !builder.config.compiler_docs {
-            builder.info("\tskipping - compiler docs disabled");
             return distdir(builder).join(format!("{}-{}.tar.gz", name, host));
         }
 
@@ -179,6 +178,9 @@ impl Step for RustcDocs {
            .arg("--component-name=rustc-docs")
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--bulk-dirs=share/doc/rust/html");
+
+        builder.info(&format!("Dist compiler docs ({})", host));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         builder.remove_dir(&image);
 
@@ -350,6 +352,7 @@ impl Step for Mingw {
         }
 
         builder.info(&format!("Dist mingw ({})", host));
+        let _time = timeit(builder);
         let name = pkgname(builder, "rust-mingw");
         let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
         let _ = fs::remove_dir_all(&image);
@@ -403,7 +406,6 @@ impl Step for Rustc {
         let compiler = self.compiler;
         let host = self.compiler.host;
 
-        builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host));
         let name = pkgname(builder, "rustc");
         let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
         let _ = fs::remove_dir_all(&image);
@@ -460,6 +462,9 @@ impl Step for Rustc {
            .arg(format!("--package-name={}-{}", name, host))
            .arg("--component-name=rustc")
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         builder.remove_dir(&image);
         builder.remove_dir(&overlay);
@@ -662,8 +667,6 @@ impl Step for Std {
         let target = self.target;
 
         let name = pkgname(builder, "rust-std");
-        builder.info(&format!("Dist std stage{} ({} -> {})",
-            compiler.stage, &compiler.host, target));
 
         // The only true set of target libraries came from the build triple, so
         // let's reduce redundant work by only producing archives from that host.
@@ -714,6 +717,10 @@ impl Step for Std {
            .arg(format!("--package-name={}-{}", name, target))
            .arg(format!("--component-name=rust-std-{}", target))
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info(&format!("Dist std stage{} ({} -> {})",
+            compiler.stage, &compiler.host, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         builder.remove_dir(&image);
         distdir(builder).join(format!("{}-{}.tar.gz", name, target))
@@ -754,11 +761,9 @@ impl Step for Analysis {
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
-        builder.info("Dist analysis");
         let name = pkgname(builder, "rust-analysis");
 
         if &compiler.host != builder.config.build {
-            builder.info("\tskipping, not a build host");
             return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
         }
 
@@ -786,6 +791,9 @@ impl Step for Analysis {
            .arg(format!("--package-name={}-{}", name, target))
            .arg(format!("--component-name=rust-analysis-{}", target))
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info("Dist analysis");
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         builder.remove_dir(&image);
         distdir(builder).join(format!("{}-{}.tar.gz", name, target))
@@ -874,8 +882,6 @@ impl Step for Src {
 
     /// Creates the `rust-src` installer component
     fn run(self, builder: &Builder<'_>) -> PathBuf {
-        builder.info("Dist src");
-
         let name = pkgname(builder, "rust-src");
         let image = tmpdir(builder).join(format!("{}-image", name));
         let _ = fs::remove_dir_all(&image);
@@ -930,6 +936,9 @@ impl Step for Src {
            .arg(format!("--package-name={}", name))
            .arg("--component-name=rust-src")
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info("Dist src");
+        let _time = timeit(builder);
         builder.run(&mut cmd);
 
         builder.remove_dir(&image);
@@ -957,8 +966,6 @@ impl Step for PlainSourceTarball {
 
     /// Creates the plain source tarball
     fn run(self, builder: &Builder<'_>) -> PathBuf {
-        builder.info("Create plain source tarball");
-
         // Make sure that the root folder of tarball has the correct name
         let plain_name = format!("{}-src", pkgname(builder, "rustc"));
         let plain_dst_src = tmpdir(builder).join(&plain_name);
@@ -1020,6 +1027,9 @@ impl Step for PlainSourceTarball {
            .arg("--output").arg(&tarball)
            .arg("--work-dir=.")
            .current_dir(tmpdir(builder));
+
+        builder.info("Create plain source tarball");
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         distdir(builder).join(&format!("{}.tar.gz", plain_name))
     }
@@ -1073,7 +1083,6 @@ impl Step for Cargo {
         let compiler = self.compiler;
         let target = self.target;
 
-        builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/cargo");
         let etc = src.join("src/etc");
         let release_num = builder.release_num("cargo");
@@ -1126,6 +1135,9 @@ impl Step for Cargo {
            .arg(format!("--package-name={}-{}", name, target))
            .arg("--component-name=cargo")
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         distdir(builder).join(format!("{}-{}.tar.gz", name, target))
     }
@@ -1161,7 +1173,6 @@ impl Step for Rls {
         let target = self.target;
         assert!(builder.config.extended);
 
-        builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/rls");
         let release_num = builder.release_num("rls");
         let name = pkgname(builder, "rls");
@@ -1210,6 +1221,8 @@ impl Step for Rls {
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--component-name=rls-preview");
 
+        builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
     }
@@ -1245,7 +1258,6 @@ impl Step for Clippy {
         let target = self.target;
         assert!(builder.config.extended);
 
-        builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/clippy");
         let release_num = builder.release_num("clippy");
         let name = pkgname(builder, "clippy");
@@ -1299,6 +1311,8 @@ impl Step for Clippy {
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--component-name=clippy-preview");
 
+        builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
     }
@@ -1334,7 +1348,6 @@ impl Step for Miri {
         let target = self.target;
         assert!(builder.config.extended);
 
-        builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/miri");
         let release_num = builder.release_num("miri");
         let name = pkgname(builder, "miri");
@@ -1389,6 +1402,8 @@ impl Step for Miri {
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--component-name=miri-preview");
 
+        builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
     }
@@ -1423,7 +1438,6 @@ impl Step for Rustfmt {
         let compiler = self.compiler;
         let target = self.target;
 
-        builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/rustfmt");
         let release_num = builder.release_num("rustfmt");
         let name = pkgname(builder, "rustfmt");
@@ -1476,6 +1490,8 @@ impl Step for Rustfmt {
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--component-name=rustfmt-preview");
 
+        builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
     }
@@ -1576,6 +1592,7 @@ impl Step for Extended {
             input_tarballs.push(tarball);
         }
 
+        builder.info("building combined installer");
         let mut cmd = rust_installer(builder);
         cmd.arg("combine")
             .arg("--product-name=Rust")
@@ -1587,7 +1604,9 @@ impl Step for Extended {
             .arg("--legacy-manifest-dirs=rustlib,cargo")
             .arg("--input-tarballs").arg(input_tarballs)
             .arg("--non-installed-overlay").arg(&overlay);
+        let time = timeit(&builder);
         builder.run(&mut cmd);
+        drop(time);
 
         let mut license = String::new();
         license += &builder.read(&builder.src.join("COPYRIGHT"));
@@ -1643,6 +1662,7 @@ impl Step for Extended {
         };
 
         if target.contains("apple-darwin") {
+            builder.info("building pkg installer");
             let pkg = tmp.join("pkg");
             let _ = fs::remove_dir_all(&pkg);
 
@@ -1692,6 +1712,7 @@ impl Step for Extended {
                                                     pkgname(builder, "rust"),
                                                     target)))
                 .arg("--package-path").arg(&pkg);
+            let _time = timeit(builder);
             builder.run(&mut cmd);
         }
 
@@ -1742,14 +1763,18 @@ impl Step for Extended {
             builder.create(&exe.join("LICENSE.txt"), &license);
 
             // Generate exe installer
+            builder.info("building `exe` installer with `iscc`");
             let mut cmd = Command::new("iscc");
             cmd.arg("rust.iss")
+                .arg("/Q")
                 .current_dir(&exe);
             if target.contains("windows-gnu") {
                 cmd.arg("/dMINGW");
             }
             add_env(builder, &mut cmd, target);
+            let time = timeit(builder);
             builder.run(&mut cmd);
+            drop(time);
             builder.install(&exe.join(format!("{}-{}.exe", pkgname(builder, "rust"), target)),
                     &distdir(builder),
                     0o755);
@@ -1914,6 +1939,7 @@ impl Step for Extended {
             builder.install(&etc.join("gfx/banner.bmp"), &exe, 0o644);
             builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, 0o644);
 
+            builder.info(&format!("building `msi` installer with {:?}", light));
             let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target);
             let mut cmd = Command::new(&light);
             cmd.arg("-nologo")
@@ -1946,6 +1972,7 @@ impl Step for Extended {
             // ICE57 wrongly complains about the shortcuts
             cmd.arg("-sice:ICE57");
 
+            let _time = timeit(builder);
             builder.run(&mut cmd);
 
             if !builder.config.dry_run {
@@ -2114,6 +2141,7 @@ impl Step for LlvmTools {
         }
 
         builder.info(&format!("Dist LlvmTools ({})", target));
+        let _time = timeit(builder);
         let src = builder.src.join("src/llvm-project/llvm");
         let name = pkgname(builder, "llvm-tools");
 
diff --git a/src/etc/installer/exe/rust.iss b/src/etc/installer/exe/rust.iss
index c22d60b6c5d..70648beac38 100644
--- a/src/etc/installer/exe/rust.iss
+++ b/src/etc/installer/exe/rust.iss
@@ -25,9 +25,9 @@ SourceDir=.\
 OutputBaseFilename={#CFG_PACKAGE_NAME}-{#CFG_BUILD}
 DefaultDirName={sd}\Rust
 
-Compression=lzma2/ultra
-InternalCompressLevel=ultra
-SolidCompression=true
+Compression=lzma2/normal
+InternalCompressLevel=normal
+SolidCompression=no
 
 ChangesEnvironment=true
 ChangesAssociations=no
diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs
index a471ccc6f5b..a2e378f7b1d 100644
--- a/src/etc/installer/msi/rust.wxs
+++ b/src/etc/installer/msi/rust.wxs
@@ -152,7 +152,7 @@
         </Upgrade>
 
         <!-- Specifies a single cab file to be embedded in the installer's .msi. -->
-        <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
+        <MediaTemplate EmbedCab="yes" CompressionLevel="mszip" />
 
         <!-- Send a WM_SETTINGCHANGE message to tell processes like explorer to update their
              environments so any new command prompts get the updated %PATH% -->
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index c53f4e49971..27e4d1237c2 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -659,11 +659,11 @@ pub struct VtableTraitAliasData<'tcx, N> {
 }
 
 /// Creates predicate obligations from the generic bounds.
-pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
-                                     param_env: ty::ParamEnv<'tcx>,
-                                     generic_bounds: &ty::InstantiatedPredicates<'tcx>)
-                                     -> PredicateObligations<'tcx>
-{
+pub fn predicates_for_generics<'tcx>(
+    cause: ObligationCause<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    generic_bounds: &ty::InstantiatedPredicates<'tcx>,
+) -> PredicateObligations<'tcx> {
     util::predicates_for_generics(cause, 0, param_env, generic_bounds)
 }
 
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 3d36790c94b..3e5520dd465 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -513,20 +513,19 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>(
 }
 
 /// See [`super::obligations_for_generics`].
-pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
-                                     recursion_depth: usize,
-                                     param_env: ty::ParamEnv<'tcx>,
-                                     generic_bounds: &ty::InstantiatedPredicates<'tcx>)
-                                     -> Vec<PredicateObligation<'tcx>>
-{
-    debug!("predicates_for_generics(generic_bounds={:?})",
-           generic_bounds);
-
-    generic_bounds.predicates.iter().map(|predicate| {
-        Obligation { cause: cause.clone(),
-                     recursion_depth,
-                     param_env,
-                     predicate: predicate.clone() }
+pub fn predicates_for_generics<'tcx>(
+    cause: ObligationCause<'tcx>,
+    recursion_depth: usize,
+    param_env: ty::ParamEnv<'tcx>,
+    generic_bounds: &ty::InstantiatedPredicates<'tcx>,
+) -> Vec<PredicateObligation<'tcx>> {
+    debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);
+
+    generic_bounds.predicates.iter().map(|predicate| Obligation {
+        cause: cause.clone(),
+        recursion_depth,
+        param_env,
+        predicate: predicate.clone(),
     }).collect()
 }
 
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 5409cbc4129..125c48f5f31 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -275,10 +275,10 @@ impl<'tcx> TyCtxt<'tcx> {
                                  `.await`ing on both of them");
                     }
                 }
-                if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) =
-                       (&values.found.sty, &values.expected.sty) // Issue #53280
-                {
-                    if let Ok(snippet) = self.sess.source_map().span_to_snippet(sp) {
+                match (&values.expected.sty, &values.found.sty) {
+                    (ty::Float(_), ty::Infer(ty::IntVar(_))) => if let Ok( // Issue #53280
+                        snippet,
+                    ) = self.sess.source_map().span_to_snippet(sp) {
                         if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
                             db.span_suggestion(
                                 sp,
@@ -287,8 +287,96 @@ impl<'tcx> TyCtxt<'tcx> {
                                 Applicability::MachineApplicable
                             );
                         }
+                    },
+                    (ty::Param(_), ty::Param(_)) => {
+                        db.note("a type parameter was expected, but a different one was found; \
+                                 you might be missing a type parameter or trait bound");
+                        db.note("for more information, visit \
+                                 https://doc.rust-lang.org/book/ch10-02-traits.html\
+                                 #traits-as-parameters");
+                    }
+                    (ty::Projection(_), ty::Projection(_)) => {
+                        db.note("an associated type was expected, but a different one was found");
+                    }
+                    (ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => {
+                        db.note("you might be missing a type parameter or trait bound");
+                    }
+                    (ty::Param(_), _) | (_, ty::Param(_)) => {
+                        db.help("type parameters must be constrained to match other types");
+                        if self.sess.teach(&db.get_code().unwrap()) {
+                            db.help("given a type parameter `T` and a method `foo`:
+```
+trait Trait<T> { fn foo(&self) -> T; }
+```
+the only ways to implement method `foo` are:
+- constrain `T` with an explicit type:
+```
+impl Trait<String> for X {
+    fn foo(&self) -> String { String::new() }
+}
+```
+- add a trait bound to `T` and call a method on that trait that returns `Self`:
+```
+impl<T: std::default::Default> Trait<T> for X {
+    fn foo(&self) -> T { <T as std::default::Default>::default() }
+}
+```
+- change `foo` to return an argument of type `T`:
+```
+impl<T> Trait<T> for X {
+    fn foo(&self, x: T) -> T { x }
+}
+```");
+                        }
+                        db.note("for more information, visit \
+                                 https://doc.rust-lang.org/book/ch10-02-traits.html\
+                                 #traits-as-parameters");
+                    }
+                    (ty::Projection(_), _) => {
+                        db.note(&format!(
+                            "consider constraining the associated type `{}` to `{}` or calling a \
+                             method that returns `{}`",
+                            values.expected,
+                            values.found,
+                            values.expected,
+                        ));
+                        if self.sess.teach(&db.get_code().unwrap()) {
+                            db.help("given an associated type `T` and a method `foo`:
+```
+trait Trait {
+    type T;
+    fn foo(&self) -> Self::T;
+}
+```
+the only way of implementing method `foo` is to constrain `T` with an explicit associated type:
+```
+impl Trait for X {
+    type T = String;
+    fn foo(&self) -> Self::T { String::new() }
+}
+```");
+                        }
+                        db.note("for more information, visit \
+                                 https://doc.rust-lang.org/book/ch19-03-advanced-traits.html");
+                    }
+                    (_, ty::Projection(_)) => {
+                        db.note(&format!(
+                            "consider constraining the associated type `{}` to `{}`",
+                            values.found,
+                            values.expected,
+                        ));
+                        db.note("for more information, visit \
+                                 https://doc.rust-lang.org/book/ch19-03-advanced-traits.html");
                     }
+                    _ => {}
                 }
+                debug!(
+                    "note_and_explain_type_err expected={:?} ({:?}) found={:?} ({:?})",
+                    values.expected,
+                    values.expected.sty,
+                    values.found,
+                    values.found.sty,
+                );
             },
             CyclicTy(ty) => {
                 // Watch out for various cases of cyclic types and try to explain.
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 7cc1e634cf8..795721f3b3f 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1407,10 +1407,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                     }
                 }
                 ty::FnPtr(_) => {
-                    if self.mode.requires_const_checking() {
+                    let unleash_miri = self
+                        .tcx
+                        .sess
+                        .opts
+                        .debugging_opts
+                        .unleash_the_miri_inside_of_you;
+                    if self.mode.requires_const_checking() && !unleash_miri {
                         let mut err = self.tcx.sess.struct_span_err(
                             self.span,
-                            &format!("function pointers are not allowed in const fn"));
+                            "function pointers are not allowed in const fn"
+                        );
                         err.emit();
                     }
                 }
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index df8bd3fa75e..cd1689f21cc 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -445,6 +445,12 @@ impl<'a> LateResolutionVisitor<'a, '_> {
             (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => {
                 bad_struct_syntax_suggestion();
             }
+            (Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), _) if ns == ValueNS => {
+                err.span_label(
+                    span,
+                    format!("did you mean `{} ( /* fields */ )`?", path_str),
+                );
+            }
             (Res::SelfTy(..), _) if ns == ValueNS => {
                 err.span_label(span, fallback_label);
                 err.note("can't use `Self` as a constructor, you must use the implemented struct");
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index d93a4052cd3..d687a5084e2 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -676,18 +676,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         } else {
             // Pattern has wrong number of fields.
-            self.e0023(pat.span, res, &subpats, &variant.fields);
+            self.e0023(pat.span, res, &subpats, &variant.fields, expected);
             on_error();
             return tcx.types.err;
         }
         pat_ty
     }
 
-    fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P<Pat>], fields: &[ty::FieldDef]) {
+    fn e0023(
+        &self,
+        pat_span: Span,
+        res: Res,
+        subpats: &'tcx [P<Pat>],
+        fields: &[ty::FieldDef],
+        expected: Ty<'tcx>
+    ) {
         let subpats_ending = pluralise!(subpats.len());
         let fields_ending = pluralise!(fields.len());
+        let missing_parenthesis = match expected.sty {
+            ty::Adt(_, substs) if fields.len() == 1 => {
+                let field_ty = fields[0].ty(self.tcx, substs);
+                match field_ty.sty {
+                    ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(),
+                    _ => false,
+                }
+            }
+            _ => false,
+        };
         let res_span = self.tcx.def_span(res.def_id());
-        struct_span_err!(
+        let mut err = struct_span_err!(
             self.tcx.sess,
             pat_span,
             E0023,
@@ -697,15 +714,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             res.descr(),
             fields.len(),
             fields_ending,
-        )
-            .span_label(pat_span, format!(
+        );
+        err.span_label(pat_span, format!(
                 "expected {} field{}, found {}",
                 fields.len(),
                 fields_ending,
                 subpats.len(),
             ))
-            .span_label(res_span, format!("{} defined here", res.descr()))
-            .emit();
+            .span_label(res_span, format!("{} defined here", res.descr()));
+
+        if missing_parenthesis {
+            err.multipart_suggestion(
+                "missing parenthesis",
+                vec![(subpats[0].span.shrink_to_lo(), "(".to_string()),
+                    (subpats[subpats.len()-1].span.shrink_to_hi(), ")".to_string())],
+                Applicability::MachineApplicable,
+            );
+        }
+
+        err.emit();
     }
 
     fn check_pat_tuple(
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index f1d0e0b68f7..60560ae96de 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -9,9 +9,6 @@ use crate::ThinVec;
 use rustc_target::spec::abi::Abi;
 use syntax_pos::{Pos, Span};
 
-// Left so that Cargo tests don't break, this can be removed once those no longer use it
-pub trait AstBuilder {}
-
 impl<'a> ExtCtxt<'a> {
     pub fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
         self.path_all(span, false, strs, vec![], vec![])
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 71fe7ec06b85f612fc0e4eb4134c7a7d0f23fac
+Subproject 8adf9bdccfefb8d03f0e8db3b012fb41da1580a
diff --git a/src/test/ui/associated-const/associated-const-generic-obligations.stderr b/src/test/ui/associated-const/associated-const-generic-obligations.stderr
index eeee26a7567..ca6118cb3ba 100644
--- a/src/test/ui/associated-const/associated-const-generic-obligations.stderr
+++ b/src/test/ui/associated-const/associated-const-generic-obligations.stderr
@@ -9,6 +9,8 @@ LL |     const FROM: &'static str = "foo";
    |
    = note: expected type `<T as Foo>::Out`
               found type `&'static str`
+   = note: consider constraining the associated type `<T as Foo>::Out` to `&'static str` or calling a method that returns `<T as Foo>::Out`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr
index 0f8c5257d44..c9d88b7af07 100644
--- a/src/test/ui/associated-types/associated-types-eq-3.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-3.stderr
@@ -6,6 +6,8 @@ LL |     let _: Bar = x.boo();
    |
    = note: expected type `Bar`
               found type `<I as Foo>::A`
+   = note: consider constraining the associated type `<I as Foo>::A` to `Bar`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
   --> $DIR/associated-types-eq-3.rs:38:5
diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr
index 7d6c025d69d..e037bd851ca 100644
--- a/src/test/ui/associated-types/associated-types-issue-20346.stderr
+++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr
@@ -9,6 +9,8 @@ LL |     is_iterator_of::<Option<T>, _>(&adapter);
    |
    = note: expected type `T`
               found type `std::option::Option<T>`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
index 4a2a6d03c60..d6328a64c7c 100644
--- a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
+++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
@@ -9,6 +9,8 @@ LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
    |
    = note: expected type `<T as Foo>::Y`
               found type `i32`
+   = note: consider constraining the associated type `<T as Foo>::Y` to `i32` or calling a method that returns `<T as Foo>::Y`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
   --> $DIR/associated-types-multiple-types-one-trait.rs:18:5
@@ -21,6 +23,8 @@ LL | fn want_x<T:Foo<X=u32>>(t: &T) { }
    |
    = note: expected type `<T as Foo>::X`
               found type `u32`
+   = note: consider constraining the associated type `<T as Foo>::X` to `u32` or calling a method that returns `<T as Foo>::X`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/compare-method/reordered-type-param.stderr b/src/test/ui/compare-method/reordered-type-param.stderr
index a33908c01c8..8176e96d6de 100644
--- a/src/test/ui/compare-method/reordered-type-param.stderr
+++ b/src/test/ui/compare-method/reordered-type-param.stderr
@@ -9,6 +9,8 @@ LL |   fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
    |
    = note: expected type `fn(&E, F) -> F`
               found type `fn(&E, G) -> G`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.rs b/src/test/ui/consts/const-eval/const_fn_ptr.rs
new file mode 100644
index 00000000000..498f801db81
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr.rs
@@ -0,0 +1,37 @@
+// run-pass
+// compile-flags: -Zunleash-the-miri-inside-of-you
+#![feature(const_fn)]
+
+fn double(x: usize) -> usize { x * 2 }
+const fn double_const(x: usize) -> usize { x * 2 }
+
+const X: fn(usize) -> usize = double;
+const X_const: fn(usize) -> usize = double_const;
+
+const fn bar(x: usize) -> usize {
+    X(x)
+}
+
+const fn bar_const(x: usize) -> usize {
+    X_const(x)
+}
+
+const fn foo(x: fn(usize) -> usize, y: usize)  -> usize {
+    x(y)
+}
+
+fn main() {
+    const Y: usize = bar_const(2);
+    assert_eq!(Y, 4);
+    let y = bar_const(2);
+    assert_eq!(y, 4);
+    let y = bar(2);
+    assert_eq!(y, 4);
+
+    const Z: usize = foo(double_const, 2);
+    assert_eq!(Z, 4);
+    let z = foo(double_const, 2);
+    assert_eq!(z, 4);
+    let z = foo(double, 2);
+    assert_eq!(z, 4);
+}
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.stderr b/src/test/ui/consts/const-eval/const_fn_ptr.stderr
new file mode 100644
index 00000000000..41452ee59eb
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr.stderr
@@ -0,0 +1,152 @@
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:25:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:25:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:25:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:27:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:27:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:27:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:29:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:29:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:29:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:32:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:32:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:32:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:34:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:34:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:34:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:36:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:36:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:36:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: constant `X_const` should have an upper case name
+  --> $DIR/const_fn_ptr.rs:9:7
+   |
+LL | const X_const: fn(usize) -> usize = double_const;
+   |       ^^^^^^^ help: convert the identifier to upper case: `X_CONST`
+   |
+   = note: `#[warn(non_upper_case_globals)]` on by default
+
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
new file mode 100644
index 00000000000..14bd6558e7f
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
@@ -0,0 +1,13 @@
+// run-pass
+// compile-flags: -Zunleash-the-miri-inside-of-you
+#![feature(const_fn)]
+#![allow(unused)]
+
+fn double(x: usize) -> usize { x * 2 }
+const X: fn(usize) -> usize = double;
+
+const fn bar(x: usize) -> usize {
+    X(x) // FIXME: this should error someday
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
new file mode 100644
index 00000000000..74c60f9a2a5
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
@@ -0,0 +1,26 @@
+// compile-flags: -Zunleash-the-miri-inside-of-you
+#![feature(const_fn)]
+#![allow(const_err)]
+
+fn double(x: usize) -> usize { x * 2 }
+const X: fn(usize) -> usize = double;
+
+const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
+    x(y)
+}
+
+const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
+const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
+
+fn main() {
+    assert_eq!(Y, 4);
+    //~^ ERROR evaluation of constant expression failed
+    //~^^ WARN skipping const checks
+    //~^^^ WARN skipping const checks
+    //~^^^^ WARN skipping const checks
+    assert_eq!(Z, 4);
+    //~^ ERROR evaluation of constant expression failed
+    //~^^ WARN skipping const checks
+    //~^^^ WARN skipping const checks
+    //~^^^^ WARN skipping const checks
+}
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
new file mode 100644
index 00000000000..611cc5313c0
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
@@ -0,0 +1,71 @@
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:16:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:16:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:16:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:21:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:21:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:21:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: evaluation of constant expression failed
+  --> $DIR/const_fn_ptr_fail2.rs:16:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^-^^^^^
+   |                |
+   |                referenced constant has errors
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: evaluation of constant expression failed
+  --> $DIR/const_fn_ptr_fail2.rs:21:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^-^^^^^
+   |                |
+   |                referenced constant has errors
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr
index 777b9d4a4ac..6c15e7bf282 100644
--- a/src/test/ui/empty/empty-struct-tuple-pat.stderr
+++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr
@@ -20,15 +20,16 @@ error[E0532]: expected unit struct/variant or constant, found tuple variant `E::
   --> $DIR/empty-struct-tuple-pat.rs:29:9
    |
 LL |         E::Empty4 => ()
-   |         ^^^^^^^^^ not a unit struct/variant or constant
+   |         ^^^^^^^^^ did you mean `E::Empty4 ( /* fields */ )`?
 
 error[E0532]: expected unit struct/variant or constant, found tuple variant `XE::XEmpty5`
   --> $DIR/empty-struct-tuple-pat.rs:33:9
    |
 LL |         XE::XEmpty5 => (),
    |         ^^^^-------
-   |             |
-   |             help: a unit variant with a similar name exists: `XEmpty4`
+   |         |   |
+   |         |   help: a unit variant with a similar name exists: `XEmpty4`
+   |         did you mean `XE::XEmpty5 ( /* fields */ )`?
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/error-codes/E0023.rs b/src/test/ui/error-codes/E0023.rs
index 2a97e9048a4..dc421e060e8 100644
--- a/src/test/ui/error-codes/E0023.rs
+++ b/src/test/ui/error-codes/E0023.rs
@@ -1,6 +1,7 @@
 enum Fruit {
     Apple(String, String),
     Pear(u32),
+    Orange((String, String)),
 }
 
 
@@ -10,5 +11,6 @@ fn main() {
         Fruit::Apple(a) => {}, //~ ERROR E0023
         Fruit::Apple(a, b, c) => {}, //~ ERROR E0023
         Fruit::Pear(1, 2) => {}, //~ ERROR E0023
+        Fruit::Orange(a, b) => {}, //~ ERROR E0023
     }
 }
diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr
index d04e494c258..8ae7d01ed5f 100644
--- a/src/test/ui/error-codes/E0023.stderr
+++ b/src/test/ui/error-codes/E0023.stderr
@@ -1,5 +1,5 @@
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:10:9
+  --> $DIR/E0023.rs:11:9
    |
 LL |     Apple(String, String),
    |     --------------------- tuple variant defined here
@@ -8,7 +8,7 @@ LL |         Fruit::Apple(a) => {},
    |         ^^^^^^^^^^^^^^^ expected 2 fields, found 1
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:11:9
+  --> $DIR/E0023.rs:12:9
    |
 LL |     Apple(String, String),
    |     --------------------- tuple variant defined here
@@ -17,7 +17,7 @@ LL |         Fruit::Apple(a, b, c) => {},
    |         ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
-  --> $DIR/E0023.rs:12:9
+  --> $DIR/E0023.rs:13:9
    |
 LL |     Pear(u32),
    |     --------- tuple variant defined here
@@ -25,6 +25,19 @@ LL |     Pear(u32),
 LL |         Fruit::Pear(1, 2) => {},
    |         ^^^^^^^^^^^^^^^^^ expected 1 field, found 2
 
-error: aborting due to 3 previous errors
+error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
+  --> $DIR/E0023.rs:14:9
+   |
+LL |     Orange((String, String)),
+   |     ------------------------ tuple variant defined here
+...
+LL |         Fruit::Orange(a, b) => {},
+   |         ^^^^^^^^^^^^^^^^^^^ expected 1 field, found 2
+help: missing parenthesis
+   |
+LL |         Fruit::Orange((a, b)) => {},
+   |                       ^    ^
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0023`.
diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
index c2d0e0c2a26..fd6fce938b2 100644
--- a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
+++ b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
@@ -6,6 +6,8 @@ LL |     let v = Unit2.m(
    |
    = note: expected type `Unit4`
               found type `<_ as Ty<'_>>::V`
+   = note: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as std::ops::FnOnce<((&u8,),)>>::Output == Unit3`
   --> $DIR/issue-62203-hrtb-ice.rs:38:19
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index 2c4c61a0957..99c6a8cdd6d 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -14,6 +14,8 @@ LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
    |
    = note: expected type `()`
               found type `<T as impl_trait::Trait>::Assoc`
+   = note: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
    = note: the return type of a function must have a statically known size
 
 error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
@@ -30,6 +32,8 @@ LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
    |
    = note: expected type `()`
               found type `<T as lifetimes::Trait<'static>>::Assoc`
+   = note: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
    = note: the return type of a function must have a statically known size
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr
index 3e6181adec0..e30e2626e9f 100644
--- a/src/test/ui/impl-trait/equality2.stderr
+++ b/src/test/ui/impl-trait/equality2.stderr
@@ -15,6 +15,8 @@ LL |     let _: i32 = Leak::leak(hide(0_i32));
    |
    = note: expected type `i32`
               found type `<impl Foo as Leak>::T`
+   = note: consider constraining the associated type `<impl Foo as Leak>::T` to `i32`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0308]: mismatched types
   --> $DIR/equality2.rs:38:10
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
index 357e6b026e2..e4d0a731ebf 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
+++ b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
@@ -9,6 +9,8 @@ LL |     fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
    |
    = note: expected type `fn(&(), &B, &impl Debug)`
               found type `fn(&(), &impl Debug, &B)`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/universal-mismatched-type.stderr b/src/test/ui/impl-trait/universal-mismatched-type.stderr
index d223b9672cf..d92c3f034e5 100644
--- a/src/test/ui/impl-trait/universal-mismatched-type.stderr
+++ b/src/test/ui/impl-trait/universal-mismatched-type.stderr
@@ -8,6 +8,8 @@ LL |     x
    |
    = note: expected type `std::string::String`
               found type `impl Debug`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.stderr b/src/test/ui/impl-trait/universal-two-impl-traits.stderr
index 145d6a8431b..98a70f268cf 100644
--- a/src/test/ui/impl-trait/universal-two-impl-traits.stderr
+++ b/src/test/ui/impl-trait/universal-two-impl-traits.stderr
@@ -6,6 +6,8 @@ LL |     a = y;
    |
    = note: expected type `impl Debug` (type parameter)
               found type `impl Debug` (type parameter)
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-13853.stderr b/src/test/ui/issues/issue-13853.stderr
index c57ca3e25d9..3f2d0aa87ad 100644
--- a/src/test/ui/issues/issue-13853.stderr
+++ b/src/test/ui/issues/issue-13853.stderr
@@ -9,6 +9,8 @@ LL |         self.iter()
    |
    = note: expected type `I`
               found type `std::slice::Iter<'_, N>`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0599]: no method named `iter` found for type `&G` in the current scope
   --> $DIR/issue-13853.rs:27:23
diff --git a/src/test/ui/issues/issue-20225.stderr b/src/test/ui/issues/issue-20225.stderr
index 5ab23cb55bc..4c464e6d4f6 100644
--- a/src/test/ui/issues/issue-20225.stderr
+++ b/src/test/ui/issues/issue-20225.stderr
@@ -6,6 +6,8 @@ LL |   extern "rust-call" fn call(&self, (_,): (T,)) {}
    |
    = note: expected type `extern "rust-call" fn(&Foo, (&'a T,))`
               found type `extern "rust-call" fn(&Foo, (T,))`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0053]: method `call_mut` has an incompatible type for trait
   --> $DIR/issue-20225.rs:12:3
@@ -15,6 +17,8 @@ LL |   extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
    |
    = note: expected type `extern "rust-call" fn(&mut Foo, (&'a T,))`
               found type `extern "rust-call" fn(&mut Foo, (T,))`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0053]: method `call_once` has an incompatible type for trait
   --> $DIR/issue-20225.rs:20:3
@@ -24,6 +28,8 @@ LL |   extern "rust-call" fn call_once(self, (_,): (T,)) {}
    |
    = note: expected type `extern "rust-call" fn(Foo, (&'a T,))`
               found type `extern "rust-call" fn(Foo, (T,))`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-24204.stderr b/src/test/ui/issues/issue-24204.stderr
index eb9aada389f..9658f6980be 100644
--- a/src/test/ui/issues/issue-24204.stderr
+++ b/src/test/ui/issues/issue-24204.stderr
@@ -9,6 +9,7 @@ LL | fn test<T: Trait<B=i32>>(b: i32) -> T where T::A: MultiDispatch<i32> { T::n
    |
    = note: expected type `<<T as Trait>::A as MultiDispatch<i32>>::O`
               found type `T`
+   = note: you might be missing a type parameter or trait bound
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-2951.stderr b/src/test/ui/issues/issue-2951.stderr
index 58e28c1a9dc..a6ccc4835fa 100644
--- a/src/test/ui/issues/issue-2951.stderr
+++ b/src/test/ui/issues/issue-2951.stderr
@@ -6,6 +6,8 @@ LL |     xx = y;
    |
    = note: expected type `T`
               found type `U`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-32004.stderr b/src/test/ui/issues/issue-32004.stderr
index f8c418b25a0..b56fa949acb 100644
--- a/src/test/ui/issues/issue-32004.stderr
+++ b/src/test/ui/issues/issue-32004.stderr
@@ -3,8 +3,9 @@ error[E0532]: expected unit struct/variant or constant, found tuple variant `Foo
    |
 LL |         Foo::Bar => {}
    |         ^^^^^---
-   |              |
-   |              help: a unit variant with a similar name exists: `Baz`
+   |         |    |
+   |         |    help: a unit variant with a similar name exists: `Baz`
+   |         did you mean `Foo::Bar ( /* fields */ )`?
 
 error[E0532]: expected tuple struct/variant, found unit struct `S`
   --> $DIR/issue-32004.rs:16:9
diff --git a/src/test/ui/issues/issue-32323.stderr b/src/test/ui/issues/issue-32323.stderr
index 6256dc0c550..9c11a02923c 100644
--- a/src/test/ui/issues/issue-32323.stderr
+++ b/src/test/ui/issues/issue-32323.stderr
@@ -8,6 +8,8 @@ LL | pub fn f<'a, T: Tr<'a>>() -> <T as Tr<'a>>::Out {}
    |
    = note: expected type `<T as Tr<'a>>::Out`
               found type `()`
+   = note: consider constraining the associated type `<T as Tr<'a>>::Out` to `()` or calling a method that returns `<T as Tr<'a>>::Out`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-63983.rs b/src/test/ui/issues/issue-63983.rs
new file mode 100644
index 00000000000..c1c79091fc8
--- /dev/null
+++ b/src/test/ui/issues/issue-63983.rs
@@ -0,0 +1,15 @@
+enum MyEnum {
+    Tuple(i32),
+    Struct{ s: i32 },
+}
+
+fn foo(en: MyEnum) {
+    match en {
+        MyEnum::Tuple => "",
+        //~^ ERROR expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple`
+        MyEnum::Struct => "",
+        //~^ ERROR expected unit struct/variant or constant, found struct variant `MyEnum::Struct`
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr
new file mode 100644
index 00000000000..67acd1d57c2
--- /dev/null
+++ b/src/test/ui/issues/issue-63983.stderr
@@ -0,0 +1,15 @@
+error[E0532]: expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple`
+  --> $DIR/issue-63983.rs:8:9
+   |
+LL |         MyEnum::Tuple => "",
+   |         ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple ( /* fields */ )`?
+
+error[E0532]: expected unit struct/variant or constant, found struct variant `MyEnum::Struct`
+  --> $DIR/issue-63983.rs:10:9
+   |
+LL |         MyEnum::Struct => "",
+   |         ^^^^^^^^^^^^^^ did you mean `MyEnum::Struct { /* fields */ }`?
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0532`.
diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr
index f0306701613..4a9afb9d249 100644
--- a/src/test/ui/mismatched_types/issue-35030.stderr
+++ b/src/test/ui/mismatched_types/issue-35030.stderr
@@ -6,6 +6,8 @@ LL |         Some(true)
    |
    = note: expected type `bool` (type parameter)
               found type `bool` (bool)
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/specialization/specialization-default-projection.stderr b/src/test/ui/specialization/specialization-default-projection.stderr
index ab0bdc44cff..43cebd7f9c2 100644
--- a/src/test/ui/specialization/specialization-default-projection.stderr
+++ b/src/test/ui/specialization/specialization-default-projection.stderr
@@ -9,6 +9,8 @@ LL |     ()
    |
    = note: expected type `<T as Foo>::Assoc`
               found type `()`
+   = note: consider constraining the associated type `<T as Foo>::Assoc` to `()` or calling a method that returns `<T as Foo>::Assoc`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0308]: mismatched types
   --> $DIR/specialization-default-projection.rs:28:5
@@ -23,6 +25,8 @@ LL |     generic::<()>()
    |
    = note: expected type `()`
               found type `<() as Foo>::Assoc`
+   = note: consider constraining the associated type `<() as Foo>::Assoc` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/specialization/specialization-default-types.stderr b/src/test/ui/specialization/specialization-default-types.stderr
index 1192b0e5cfa..932087421fb 100644
--- a/src/test/ui/specialization/specialization-default-types.stderr
+++ b/src/test/ui/specialization/specialization-default-types.stderr
@@ -8,6 +8,8 @@ LL |         Box::new(self)
    |
    = note: expected type `<T as Example>::Output`
               found type `std::boxed::Box<T>`
+   = note: consider constraining the associated type `<T as Example>::Output` to `std::boxed::Box<T>` or calling a method that returns `<T as Example>::Output`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0308]: mismatched types
   --> $DIR/specialization-default-types.rs:25:5
@@ -19,6 +21,8 @@ LL |     Example::generate(t)
    |
    = note: expected type `std::boxed::Box<T>`
               found type `<T as Example>::Output`
+   = note: consider constraining the associated type `<T as Example>::Output` to `std::boxed::Box<T>`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/structs/struct-path-self-type-mismatch.stderr b/src/test/ui/structs/struct-path-self-type-mismatch.stderr
index 72c6d7ae22b..b905cd1a294 100644
--- a/src/test/ui/structs/struct-path-self-type-mismatch.stderr
+++ b/src/test/ui/structs/struct-path-self-type-mismatch.stderr
@@ -12,6 +12,8 @@ LL |             inner: u
    |
    = note: expected type `T`
               found type `U`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0308]: mismatched types
   --> $DIR/struct-path-self-type-mismatch.rs:13:9
@@ -27,6 +29,8 @@ LL | |         }
    |
    = note: expected type `Foo<U>`
               found type `Foo<T>`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index ee73622cb7b..a0a617fdbbc 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -6,6 +6,8 @@ LL |         Self::TSVariant(());
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:15:27
@@ -27,6 +29,8 @@ LL |         Self::<()>::TSVariant(());
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:20:16
@@ -48,6 +52,8 @@ LL |         Self::SVariant { v: () };
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:28:26
@@ -63,6 +69,8 @@ LL |         Self::SVariant::<()> { v: () };
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:31:16
@@ -78,6 +86,8 @@ LL |         Self::<()>::SVariant { v: () };
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:34:16
@@ -99,6 +109,8 @@ LL |         Self::<()>::SVariant::<()> { v: () };
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:41:26
diff --git a/src/test/ui/type/type-parameter-names.stderr b/src/test/ui/type/type-parameter-names.stderr
index 9acae5c376d..3397eec9e05 100644
--- a/src/test/ui/type/type-parameter-names.stderr
+++ b/src/test/ui/type/type-parameter-names.stderr
@@ -8,6 +8,8 @@ LL |     x
    |
    = note: expected type `Bar`
               found type `Foo`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/type-params-in-different-spaces-1.stderr b/src/test/ui/type/type-params-in-different-spaces-1.stderr
index 0448a28ea8e..a10bf4e0b77 100644
--- a/src/test/ui/type/type-params-in-different-spaces-1.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-1.stderr
@@ -6,6 +6,8 @@ LL |         *self + rhs
    |
    = note: expected type `Self`
               found type `T`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/type-params-in-different-spaces-3.stderr b/src/test/ui/type/type-params-in-different-spaces-3.stderr
index e25f79947c7..9f0fa5a0ea1 100644
--- a/src/test/ui/type/type-params-in-different-spaces-3.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-3.stderr
@@ -8,6 +8,8 @@ LL |         u
    |
    = note: expected type `Self`
               found type `X`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error