about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock8
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0544.md29
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lexer/src/lib.rs14
-rw-r--r--compiler/rustc_middle/src/middle/limits.rs7
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs3
-rw-r--r--compiler/rustc_mir/src/const_eval/machine.rs19
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs12
-rw-r--r--library/core/src/cell.rs2
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/sys/unix/os.rs7
-rw-r--r--library/std/src/sys/unix/os/tests.rs2
-rw-r--r--library/std/src/sys/unix/process/process_common.rs2
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/unstable-book/src/compiler-flags/move-size-limit.md10
-rw-r--r--src/test/ui/async-await/large_moves.attribute.stderr (renamed from src/test/ui/async-await/large_moves.stderr)8
-rw-r--r--src/test/ui/async-await/large_moves.option.stderr38
-rw-r--r--src/test/ui/async-await/large_moves.rs4
-rw-r--r--src/test/ui/issues/issue-86756.rs12
-rw-r--r--src/test/ui/issues/issue-86756.stderr46
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity.stderr2
m---------src/tools/cargo0
29 files changed, 180 insertions, 52 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 553d9d05e57..bd950310b73 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1880,9 +1880,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.93"
+version = "0.2.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
+checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -5409,9 +5409,9 @@ dependencies = [
 
 [[package]]
 name = "unicode-xid"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
 
 [[package]]
 name = "unicode_categories"
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 1aa5f995974..6f65d386f0d 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -287,6 +287,7 @@ E0539: include_str!("./error_codes/E0539.md"),
 E0541: include_str!("./error_codes/E0541.md"),
 E0542: include_str!("./error_codes/E0542.md"),
 E0543: include_str!("./error_codes/E0543.md"),
+E0544: include_str!("./error_codes/E0544.md"),
 E0545: include_str!("./error_codes/E0545.md"),
 E0546: include_str!("./error_codes/E0546.md"),
 E0547: include_str!("./error_codes/E0547.md"),
@@ -610,7 +611,6 @@ E0783: include_str!("./error_codes/E0783.md"),
     E0523,
 //  E0526, // shuffle indices are not constant
 //  E0540, // multiple rustc_deprecated attributes
-    E0544, // multiple stability levels
 //  E0548, // replaced with a generic attribute input check
 //  E0553, // multiple rustc_const_unstable attributes
 //  E0555, // replaced with a generic attribute input check
diff --git a/compiler/rustc_error_codes/src/error_codes/E0544.md b/compiler/rustc_error_codes/src/error_codes/E0544.md
new file mode 100644
index 00000000000..2227e2a06bf
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0544.md
@@ -0,0 +1,29 @@
+Multiple stability attributes were declared on the same item.
+
+Erroneous code example:
+
+```compile_fail,E0544
+#![feature(staged_api)]
+#![stable(since = "1.0.0", feature = "rust1")]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[stable(feature = "test", since = "2.0.0")] // invalid
+fn foo() {}
+```
+
+To fix this issue, ensure that each item has at most one stability attribute.
+
+```
+#![feature(staged_api)]
+#![stable(since = "1.0.0", feature = "rust1")]
+
+#[stable(feature = "test", since = "2.0.0")] // ok!
+fn foo() {}
+```
+
+See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix
+of the Book and the [Stability attributes][stability-attributes] section of the
+Rustc Dev Guide for more details.
+
+[how-rust-made-nightly]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
+[stability-attributes]: https://rustc-dev-guide.rust-lang.org/stability.html
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index b1e4e3ba395..de0d5fb0097 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -735,6 +735,7 @@ fn test_debugging_options_tracking_hash() {
     tracked!(merge_functions, Some(MergeFunctions::Disabled));
     tracked!(mir_emit_retag, true);
     tracked!(mir_opt_level, Some(4));
+    tracked!(move_size_limit, Some(4096));
     tracked!(mutable_noalias, Some(true));
     tracked!(new_llvm_pass_manager, Some(true));
     tracked!(no_generate_arange_section, true);
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index 4cb2a6ca50f..b5e6d256a99 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -273,24 +273,14 @@ pub fn is_whitespace(c: char) -> bool {
 /// a formal definition of valid identifier name.
 pub fn is_id_start(c: char) -> bool {
     // This is XID_Start OR '_' (which formally is not a XID_Start).
-    // We also add fast-path for ascii idents
-    ('a'..='z').contains(&c)
-        || ('A'..='Z').contains(&c)
-        || c == '_'
-        || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_start(c))
+    c == '_' || unicode_xid::UnicodeXID::is_xid_start(c)
 }
 
 /// True if `c` is valid as a non-first character of an identifier.
 /// See [Rust language reference](https://doc.rust-lang.org/reference/identifiers.html) for
 /// a formal definition of valid identifier name.
 pub fn is_id_continue(c: char) -> bool {
-    // This is exactly XID_Continue.
-    // We also add fast-path for ascii idents
-    ('a'..='z').contains(&c)
-        || ('A'..='Z').contains(&c)
-        || ('0'..='9').contains(&c)
-        || c == '_'
-        || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
+    unicode_xid::UnicodeXID::is_xid_continue(c)
 }
 
 /// The passed string is lexically an identifier.
diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs
index c4bfd0ebb2f..7ea4902f4bc 100644
--- a/compiler/rustc_middle/src/middle/limits.rs
+++ b/compiler/rustc_middle/src/middle/limits.rs
@@ -21,7 +21,12 @@ use std::num::IntErrorKind;
 pub fn provide(providers: &mut ty::query::Providers) {
     providers.limits = |tcx, ()| Limits {
         recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess),
-        move_size_limit: get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::move_size_limit, 0),
+        move_size_limit: get_limit(
+            tcx.hir().krate_attrs(),
+            tcx.sess,
+            sym::move_size_limit,
+            tcx.sess.opts.debugging_opts.move_size_limit.unwrap_or(0),
+        ),
         type_length_limit: get_limit(
             tcx.hir().krate_attrs(),
             tcx.sess,
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 94ac303b109..dad23d6255a 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -402,8 +402,6 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
 pub enum UnsupportedOpInfo {
     /// Free-form case. Only for errors that are never caught!
     Unsupported(String),
-    /// Could not find MIR for a function.
-    NoMirFor(DefId),
     /// Encountered a pointer where we needed raw bytes.
     ReadPointerAsBytes,
     //
@@ -421,7 +419,6 @@ impl fmt::Display for UnsupportedOpInfo {
         match self {
             Unsupported(ref msg) => write!(f, "{}", msg),
             ReadExternStatic(did) => write!(f, "cannot read from extern static ({:?})", did),
-            NoMirFor(did) => write!(f, "no MIR body is available for {:?}", did),
             ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes",),
             ThreadLocalStatic(did) => write!(f, "cannot access thread local static ({:?})", did),
         }
diff --git a/compiler/rustc_mir/src/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs
index c809f4f273a..daaf68c1d2b 100644
--- a/compiler/rustc_mir/src/const_eval/machine.rs
+++ b/compiler/rustc_mir/src/const_eval/machine.rs
@@ -212,7 +212,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
                 if ecx.tcx.is_ctfe_mir_available(def.did) {
                     Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def))
                 } else {
-                    throw_unsup!(NoMirFor(def.did))
+                    let path = ecx.tcx.def_path_str(def.did);
+                    Err(ConstEvalErrKind::NeedsRfc(format!("calling extern function `{}`", path))
+                        .into())
                 }
             }
             _ => Ok(ecx.tcx.instance_mir(instance)),
@@ -247,20 +249,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
             }
         }
         // This is a const fn. Call it.
-        Ok(Some(match ecx.load_mir(instance.def, None) {
-            Ok(body) => body,
-            Err(err) => {
-                if let err_unsup!(NoMirFor(did)) = err.kind() {
-                    let path = ecx.tcx.def_path_str(*did);
-                    return Err(ConstEvalErrKind::NeedsRfc(format!(
-                        "calling extern function `{}`",
-                        path
-                    ))
-                    .into());
-                }
-                return Err(err);
-            }
-        }))
+        Ok(Some(ecx.load_mir(instance.def, None)?))
     }
 
     fn call_intrinsic(
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 9fbe4c05ef9..0805d2f0e14 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1148,6 +1148,8 @@ options! {
         (default: no)"),
     mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED],
         "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
+    move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
+        "the size at which the `large_assignments` lint starts to be emitted"),
     mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "emit noalias metadata for mutable references (default: yes for LLVM >= 12, otherwise no)"),
     new_llvm_pass_manager: Option<bool> = (None, parse_opt_bool, [TRACKED],
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index f55e274ef8e..b82437120ce 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -21,7 +21,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{walk_generics, Visitor as _};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{Constness, GenericArg, GenericArgs};
-use rustc_middle::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
+use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef};
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::{self, Const, DefIdTree, Ty, TyCtxt, TypeFoldable};
 use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
@@ -488,12 +488,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                                 tcx.ty_error().into()
                             } else {
                                 // This is a default type parameter.
+                                let substs = substs.unwrap();
+                                if substs.iter().any(|arg| match arg.unpack() {
+                                    GenericArgKind::Type(ty) => ty.references_error(),
+                                    _ => false,
+                                }) {
+                                    // Avoid ICE #86756 when type error recovery goes awry.
+                                    return tcx.ty_error().into();
+                                }
                                 self.astconv
                                     .normalize_ty(
                                         self.span,
                                         tcx.at(self.span).type_of(param.def_id).subst_spanned(
                                             tcx,
-                                            substs.unwrap(),
+                                            substs,
                                             Some(self.span),
                                         ),
                                     )
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 24b0797f93a..f0c934edf39 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -583,7 +583,7 @@ impl<T> Cell<[T]> {
 pub struct RefCell<T: ?Sized> {
     borrow: Cell<BorrowFlag>,
     // Stores the location of the earliest currently active borrow.
-    // This gets updated whenver we go from having zero borrows
+    // This gets updated whenever we go from having zero borrows
     // to having a single borrow. When a borrow occurs, this gets included
     // in the generated `BorrowError/`BorrowMutError`
     #[cfg(feature = "debug_refcell")]
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 415d874c7fa..8494563bcd9 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -16,7 +16,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core" }
-libc = { version = "0.2.93", default-features = false, features = ['rustc-dep-of-std'] }
+libc = { version = "0.2.98", default-features = false, features = ['rustc-dep-of-std'] }
 compiler_builtins = { version = "0.1.44" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index d3c874edf2d..cc0802ed709 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -350,17 +350,14 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 pub fn current_exe() -> io::Result<PathBuf> {
-    extern "C" {
-        fn _NSGetExecutablePath(buf: *mut libc::c_char, bufsize: *mut u32) -> libc::c_int;
-    }
     unsafe {
         let mut sz: u32 = 0;
-        _NSGetExecutablePath(ptr::null_mut(), &mut sz);
+        libc::_NSGetExecutablePath(ptr::null_mut(), &mut sz);
         if sz == 0 {
             return Err(io::Error::last_os_error());
         }
         let mut v: Vec<u8> = Vec::with_capacity(sz as usize);
-        let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
+        let err = libc::_NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
         if err != 0 {
             return Err(io::Error::last_os_error());
         }
diff --git a/library/std/src/sys/unix/os/tests.rs b/library/std/src/sys/unix/os/tests.rs
index 0e1dcb390a0..c445acf2722 100644
--- a/library/std/src/sys/unix/os/tests.rs
+++ b/library/std/src/sys/unix/os/tests.rs
@@ -1,12 +1,14 @@
 use super::*;
 
 #[test]
+#[cfg(not(target_os = "vxworks"))]
 fn test_glibc_version() {
     // This mostly just tests that the weak linkage doesn't panic wildly...
     glibc_version();
 }
 
 #[test]
+#[cfg(not(target_os = "vxworks"))]
 fn test_parse_glibc_version() {
     let cases = [
         ("0.0", Some((0, 0))),
diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
index c5bdd1bda4a..f2f161e4eaa 100644
--- a/library/std/src/sys/unix/process/process_common.rs
+++ b/library/std/src/sys/unix/process/process_common.rs
@@ -50,7 +50,7 @@ cfg_if::cfg_if! {
             raw[bit / 8] |= 1 << (bit % 8);
             return 0;
         }
-    } else if #[cfg(not(target_os = "vxworks"))] {
+    } else {
         pub use libc::{sigemptyset, sigaddset};
     }
 }
diff --git a/src/doc/book b/src/doc/book
-Subproject eac55314210519238652f12b30fec9daea61f7f
+Subproject a07036f864b37896b31eb996cd7aedb489f69a1
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject af696ce8ea526445590ae0ca66a8128d2a95a69
+Subproject 3710b0cae783d0bcd2b42452a63b081473f5970
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 7a13537f96af4b9b8e3ea296d6e5c3c7ab72ce9
+Subproject f51734eb5566c826b471977747ea3d7d6915bbe
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 82d75cf423e4a7824fb36e73ccb18519d690061
+Subproject 3b7be075af5d6e402a18efff672a8a265b4596f
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 1db6bb483cc87ad3b424d9aba764fe622960a1b
+Subproject 0dc9cd4e89f00cb5230f120e1a083916386e422
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 93422c21baca585dc88357ec886a48f6ddc7d66
+Subproject 09343d6f921d2a07c66f8c41ec3d65bf1fa5255
diff --git a/src/doc/unstable-book/src/compiler-flags/move-size-limit.md b/src/doc/unstable-book/src/compiler-flags/move-size-limit.md
new file mode 100644
index 00000000000..88f022af2ec
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/move-size-limit.md
@@ -0,0 +1,10 @@
+# `move_size_limit`
+
+--------------------
+
+The `-Zmove-size-limit=N` compiler flag enables `large_assignments` lints which
+will warn when moving objects whose size exceeds `N` bytes.
+
+Lint warns only about moves in functions that participate in code generation.
+Consequently it will be ineffective for compiler invocatation that emit
+metadata only, i.e., `cargo check` like workflows.
diff --git a/src/test/ui/async-await/large_moves.stderr b/src/test/ui/async-await/large_moves.attribute.stderr
index 8c47ec0ed9d..39b7e7cb345 100644
--- a/src/test/ui/async-await/large_moves.stderr
+++ b/src/test/ui/async-await/large_moves.attribute.stderr
@@ -1,5 +1,5 @@
 error: moving 10024 bytes
-  --> $DIR/large_moves.rs:10:13
+  --> $DIR/large_moves.rs:12:13
    |
 LL |       let x = async {
    |  _____________^
@@ -17,19 +17,19 @@ LL | #![deny(large_assignments)]
    |         ^^^^^^^^^^^^^^^^^
 
 error: moving 10024 bytes
-  --> $DIR/large_moves.rs:16:14
+  --> $DIR/large_moves.rs:18:14
    |
 LL |     let z = (x, 42);
    |              ^ value moved from here
 
 error: moving 10024 bytes
-  --> $DIR/large_moves.rs:16:13
+  --> $DIR/large_moves.rs:18:13
    |
 LL |     let z = (x, 42);
    |             ^^^^^^^ value moved from here
 
 error: moving 10024 bytes
-  --> $DIR/large_moves.rs:18:13
+  --> $DIR/large_moves.rs:20:13
    |
 LL |     let a = z.0;
    |             ^^^ value moved from here
diff --git a/src/test/ui/async-await/large_moves.option.stderr b/src/test/ui/async-await/large_moves.option.stderr
new file mode 100644
index 00000000000..39b7e7cb345
--- /dev/null
+++ b/src/test/ui/async-await/large_moves.option.stderr
@@ -0,0 +1,38 @@
+error: moving 10024 bytes
+  --> $DIR/large_moves.rs:12:13
+   |
+LL |       let x = async {
+   |  _____________^
+LL | |         let y = [0; 9999];
+LL | |         dbg!(y);
+LL | |         thing(&y).await;
+LL | |         dbg!(y);
+LL | |     };
+   | |_____^ value moved from here
+   |
+note: the lint level is defined here
+  --> $DIR/large_moves.rs:1:9
+   |
+LL | #![deny(large_assignments)]
+   |         ^^^^^^^^^^^^^^^^^
+
+error: moving 10024 bytes
+  --> $DIR/large_moves.rs:18:14
+   |
+LL |     let z = (x, 42);
+   |              ^ value moved from here
+
+error: moving 10024 bytes
+  --> $DIR/large_moves.rs:18:13
+   |
+LL |     let z = (x, 42);
+   |             ^^^^^^^ value moved from here
+
+error: moving 10024 bytes
+  --> $DIR/large_moves.rs:20:13
+   |
+LL |     let a = z.0;
+   |             ^^^ value moved from here
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/async-await/large_moves.rs b/src/test/ui/async-await/large_moves.rs
index 4fac046beef..18bb538a81e 100644
--- a/src/test/ui/async-await/large_moves.rs
+++ b/src/test/ui/async-await/large_moves.rs
@@ -1,8 +1,10 @@
 #![deny(large_assignments)]
 #![feature(large_assignments)]
-#![move_size_limit = "1000"]
+#![cfg_attr(attribute, move_size_limit = "1000")]
 // build-fail
 // only-x86_64
+// revisions: attribute option
+// [option]compile-flags: -Zmove-size-limit=1000
 
 // edition:2018
 
diff --git a/src/test/ui/issues/issue-86756.rs b/src/test/ui/issues/issue-86756.rs
new file mode 100644
index 00000000000..7f864eb2850
--- /dev/null
+++ b/src/test/ui/issues/issue-86756.rs
@@ -0,0 +1,12 @@
+trait Foo<T, T = T> {}
+//~^ ERROR the name `T` is already used for a generic parameter in this item's generic parameters
+
+fn eq<A, B>() {
+    eq::<dyn, Foo>
+    //~^ ERROR cannot find type `dyn` in this scope
+    //~| ERROR missing generics for trait `Foo`
+    //~| WARN trait objects without an explicit `dyn` are deprecated
+    //~| WARN this is accepted in the current edition
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-86756.stderr b/src/test/ui/issues/issue-86756.stderr
new file mode 100644
index 00000000000..1ef21986726
--- /dev/null
+++ b/src/test/ui/issues/issue-86756.stderr
@@ -0,0 +1,46 @@
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/issue-86756.rs:1:14
+   |
+LL | trait Foo<T, T = T> {}
+   |           -  ^ already used
+   |           |
+   |           first use of `T`
+
+error[E0412]: cannot find type `dyn` in this scope
+  --> $DIR/issue-86756.rs:5:10
+   |
+LL | fn eq<A, B>() {
+   |           - help: you might be missing a type parameter: `, dyn`
+LL |     eq::<dyn, Foo>
+   |          ^^^ not found in this scope
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/issue-86756.rs:5:15
+   |
+LL |     eq::<dyn, Foo>
+   |               ^^^ help: use `dyn`: `dyn Foo`
+   |
+   = note: `#[warn(bare_trait_objects)]` on by default
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
+
+error[E0107]: missing generics for trait `Foo`
+  --> $DIR/issue-86756.rs:5:15
+   |
+LL |     eq::<dyn, Foo>
+   |               ^^^ expected at least 1 generic argument
+   |
+note: trait defined here, with at least 1 generic parameter: `T`
+  --> $DIR/issue-86756.rs:1:7
+   |
+LL | trait Foo<T, T = T> {}
+   |       ^^^ -
+help: add missing generic argument
+   |
+LL |     eq::<dyn, Foo<T>>
+   |               ^^^^^^
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0107, E0403, E0412.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
index ddf65f3a7ee..4dc68662033 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
@@ -122,5 +122,5 @@ LL | #[rustc_deprecated(since = "a", reason = "text")]
 
 error: aborting due to 19 previous errors
 
-Some errors have detailed explanations: E0539, E0541, E0542, E0543, E0546, E0547, E0549, E0550.
+Some errors have detailed explanations: E0539, E0541, E0542, E0543, E0544, E0546, E0547, E0549, E0550.
 For more information about an error, try `rustc --explain E0539`.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject cebef2951ee69617852844894164b54ed478a7d
+Subproject d21c22870e58499d6c31f1bef3bf1255eb02166