about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-30 21:50:34 +0000
committerbors <bors@rust-lang.org>2024-07-30 21:50:34 +0000
commit249cf71f11a29b3fb68e8a35969569d8bb7958ee (patch)
tree2f6c8a18af5a4fb77d189426118c3605667df0a0
parentf8060d282d42770fadd73905e3eefb85660d3278 (diff)
parent42a0cc8e71597635b34440b2a7c4bf031a838c85 (diff)
downloadrust-249cf71f11a29b3fb68e8a35969569d8bb7958ee.tar.gz
rust-249cf71f11a29b3fb68e8a35969569d8bb7958ee.zip
Auto merge of #128413 - matthiaskrgr:rollup-nrfcvdq, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #128357 (Detect non-lifetime binder params shadowing item params)
 - #128367 (CI: rfl: build the generated doctests and documentation)
 - #128376 (Mark `Parser::eat`/`check` methods as `#[must_use]`)
 - #128379 (the output in stderr expects panic-unwind)
 - #128380 (make `///` doc comments compatible with naked functions)
 - #128382 (cargo-miri: better error when we seem to run inside bootstrap but something is wrong)
 - #128398 (tidy: Fix quote in error message)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_builtin_macros/src/pattern_type.rs2
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs5
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs3
-rw-r--r--compiler/rustc_parse/src/parser/item.rs7
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs19
-rw-r--r--compiler/rustc_parse/src/parser/path.rs3
-rw-r--r--compiler/rustc_passes/src/check_attr.rs6
-rw-r--r--compiler/rustc_resolve/src/late.rs20
-rwxr-xr-xsrc/ci/docker/scripts/rfl-build.sh6
-rw-r--r--src/tools/miri/cargo-miri/src/setup.rs5
-rw-r--r--src/tools/rustfmt/src/parse/macros/lazy_static.rs12
-rw-r--r--src/tools/tidy/src/error_codes.rs2
-rw-r--r--tests/crashes/119716-2.rs2
-rw-r--r--tests/crashes/123809.rs2
-rw-r--r--tests/ui/asm/naked-functions.rs3
-rw-r--r--tests/ui/backtrace/synchronized-panic-handler.rs1
-rw-r--r--tests/ui/backtrace/synchronized-panic-handler.run.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs7
-rw-r--r--tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr15
-rw-r--r--tests/ui/traits/non_lifetime_binders/shadowed.rs18
-rw-r--r--tests/ui/traits/non_lifetime_binders/shadowed.stderr44
-rw-r--r--tests/ui/type/pattern_types/missing-is.rs8
-rw-r--r--tests/ui/type/pattern_types/missing-is.stderr8
23 files changed, 162 insertions, 40 deletions
diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs
index 87187125541..869d203f68e 100644
--- a/compiler/rustc_builtin_macros/src/pattern_type.rs
+++ b/compiler/rustc_builtin_macros/src/pattern_type.rs
@@ -24,7 +24,7 @@ fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P
     let mut parser = cx.new_parser_from_tts(stream);
 
     let ty = parser.parse_ty()?;
-    parser.eat_keyword(sym::is);
+    parser.expect_keyword(sym::is)?;
     let pat = parser.parse_pat_no_top_alt(None, None)?;
 
     Ok((ty, pat))
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index a242dc5cd58..a4d9d97045d 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -3153,7 +3153,8 @@ impl<'a> Parser<'a> {
 
                 if !require_comma {
                     arm_body = Some(expr);
-                    this.eat(&token::Comma);
+                    // Eat a comma if it exists, though.
+                    let _ = this.eat(&token::Comma);
                     Ok(Recovered::No)
                 } else if let Some((span, guar)) =
                     this.parse_arm_body_missing_braces(&expr, arrow_span)
@@ -3654,7 +3655,7 @@ impl<'a> Parser<'a> {
                         fields.push(f);
                     }
                     self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
-                    self.eat(&token::Comma);
+                    let _ = self.eat(&token::Comma);
                 }
             }
         }
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index a67e3d05551..9124c15707d 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -178,7 +178,8 @@ impl<'a> Parser<'a> {
                             span: this.prev_token.span,
                         });
 
-                        this.eat(&token::Comma);
+                        // Eat a trailing comma, if it exists.
+                        let _ = this.eat(&token::Comma);
                     }
 
                     let param = if this.check_lifetime() {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 68da0554945..baa5eb2df63 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1192,13 +1192,14 @@ impl<'a> Parser<'a> {
         mut safety: Safety,
     ) -> PResult<'a, ItemInfo> {
         let abi = self.parse_abi(); // ABI?
+        // FIXME: This recovery should be tested better.
         if safety == Safety::Default
             && self.token.is_keyword(kw::Unsafe)
             && self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Brace))
         {
             self.expect(&token::OpenDelim(Delimiter::Brace)).unwrap_err().emit();
             safety = Safety::Unsafe(self.token.span);
-            self.eat_keyword(kw::Unsafe);
+            let _ = self.eat_keyword(kw::Unsafe);
         }
         let module = ast::ForeignMod {
             safety,
@@ -1759,7 +1760,7 @@ impl<'a> Parser<'a> {
                     }
                 }
             }
-            self.eat(&token::CloseDelim(Delimiter::Brace));
+            self.expect(&token::CloseDelim(Delimiter::Brace))?;
         } else {
             let token_str = super::token_descr(&self.token);
             let where_str = if parsed_where { "" } else { "`where`, or " };
@@ -1902,7 +1903,7 @@ impl<'a> Parser<'a> {
                         if let Some(_guar) = guar {
                             // Handle a case like `Vec<u8>>,` where we can continue parsing fields
                             // after the comma
-                            self.eat(&token::Comma);
+                            let _ = self.eat(&token::Comma);
 
                             // `check_trailing_angle_brackets` already emitted a nicer error, as
                             // proven by the presence of `_guar`. We can continue parsing.
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 26ee5bfdee4..e01f605722b 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -547,6 +547,7 @@ impl<'a> Parser<'a> {
     }
 
     #[inline]
+    #[must_use]
     fn check_noexpect(&self, tok: &TokenKind) -> bool {
         self.token == *tok
     }
@@ -556,6 +557,7 @@ impl<'a> Parser<'a> {
     /// the main purpose of this function is to reduce the cluttering of the suggestions list
     /// which using the normal eat method could introduce in some cases.
     #[inline]
+    #[must_use]
     fn eat_noexpect(&mut self, tok: &TokenKind) -> bool {
         let is_present = self.check_noexpect(tok);
         if is_present {
@@ -566,6 +568,7 @@ impl<'a> Parser<'a> {
 
     /// Consumes a token 'tok' if it exists. Returns whether the given token was present.
     #[inline]
+    #[must_use]
     pub fn eat(&mut self, tok: &TokenKind) -> bool {
         let is_present = self.check(tok);
         if is_present {
@@ -577,12 +580,14 @@ impl<'a> Parser<'a> {
     /// If the next token is the given keyword, returns `true` without eating it.
     /// An expectation is also added for diagnostics purposes.
     #[inline]
+    #[must_use]
     fn check_keyword(&mut self, kw: Symbol) -> bool {
         self.expected_tokens.push(TokenType::Keyword(kw));
         self.token.is_keyword(kw)
     }
 
     #[inline]
+    #[must_use]
     fn check_keyword_case(&mut self, kw: Symbol, case: Case) -> bool {
         if self.check_keyword(kw) {
             return true;
@@ -602,6 +607,7 @@ impl<'a> Parser<'a> {
     /// Otherwise, returns `false`. An expectation is also added for diagnostics purposes.
     // Public for rustc_builtin_macros and rustfmt usage.
     #[inline]
+    #[must_use]
     pub fn eat_keyword(&mut self, kw: Symbol) -> bool {
         if self.check_keyword(kw) {
             self.bump();
@@ -615,6 +621,7 @@ impl<'a> Parser<'a> {
     /// If the case differs (and is ignored) an error is issued.
     /// This is useful for recovery.
     #[inline]
+    #[must_use]
     fn eat_keyword_case(&mut self, kw: Symbol, case: Case) -> bool {
         if self.eat_keyword(kw) {
             return true;
@@ -636,6 +643,7 @@ impl<'a> Parser<'a> {
     /// Otherwise, returns `false`. No expectation is added.
     // Public for rustc_builtin_macros usage.
     #[inline]
+    #[must_use]
     pub fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool {
         if self.token.is_keyword(kw) {
             self.bump();
@@ -648,7 +656,7 @@ impl<'a> Parser<'a> {
     /// If the given word is not a keyword, signals an error.
     /// If the next token is not the given word, signals an error.
     /// Otherwise, eats it.
-    fn expect_keyword(&mut self, kw: Symbol) -> PResult<'a, ()> {
+    pub fn expect_keyword(&mut self, kw: Symbol) -> PResult<'a, ()> {
         if !self.eat_keyword(kw) { self.unexpected() } else { Ok(()) }
     }
 
@@ -1025,8 +1033,11 @@ impl<'a> Parser<'a> {
         f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     ) -> PResult<'a, (ThinVec<T>, Trailing)> {
         let (val, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
-        if matches!(recovered, Recovered::No) {
-            self.eat(ket);
+        if matches!(recovered, Recovered::No) && !self.eat(ket) {
+            self.dcx().span_delayed_bug(
+                self.token.span,
+                "recovered but `parse_seq_to_before_end` did not give us the ket token",
+            );
         }
         Ok((val, trailing))
     }
@@ -1250,7 +1261,7 @@ impl<'a> Parser<'a> {
         if pat {
             self.psess.gated_spans.gate(sym::inline_const_pat, span);
         }
-        self.eat_keyword(kw::Const);
+        self.expect_keyword(kw::Const)?;
         let (attrs, blk) = self.parse_inner_attrs_and_block()?;
         let anon_const = AnonConst {
             id: DUMMY_NODE_ID,
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index c5111226d37..70d2c98d4f1 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -313,7 +313,8 @@ impl<'a> Parser<'a> {
                 }
 
                 // Generic arguments are found - `<`, `(`, `::<` or `::(`.
-                self.eat(&token::PathSep);
+                // First, eat `::` if it exists.
+                let _ = self.eat(&token::PathSep);
                 let lo = self.token.span;
                 let args = if self.eat_lt() {
                     // `<'a, T, A = U>`
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index a58c57041f8..7db958da25f 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -461,6 +461,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             Target::Fn
             | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
                 for other_attr in attrs {
+                    // this covers "sugared doc comments" of the form `/// ...`
+                    // it does not cover `#[doc = "..."]`, which is handled below
+                    if other_attr.is_doc_comment() {
+                        continue;
+                    }
+
                     if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
                         self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
                             span: other_attr.span,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 7e5fd82b80c..f844930ad26 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -2671,17 +2671,17 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         // Store all seen lifetimes names from outer scopes.
         let mut seen_lifetimes = FxHashSet::default();
 
-        // We also can't shadow bindings from the parent item
-        if let RibKind::AssocItem = kind {
-            let mut add_bindings_for_ns = |ns| {
-                let parent_rib = self.ribs[ns]
-                    .iter()
-                    .rfind(|r| matches!(r.kind, RibKind::Item(..)))
-                    .expect("associated item outside of an item");
+        // We also can't shadow bindings from associated parent items.
+        for ns in [ValueNS, TypeNS] {
+            for parent_rib in self.ribs[ns].iter().rev() {
                 seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
-            };
-            add_bindings_for_ns(ValueNS);
-            add_bindings_for_ns(TypeNS);
+
+                // Break at mod level, to account for nested items which are
+                // allowed to shadow generic param names.
+                if matches!(parent_rib.kind, RibKind::Module(..)) {
+                    break;
+                }
+            }
         }
 
         // Forbid shadowing lifetime bindings
diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh
index 3acc09e0b9b..d690aac27fa 100755
--- a/src/ci/docker/scripts/rfl-build.sh
+++ b/src/ci/docker/scripts/rfl-build.sh
@@ -65,4 +65,8 @@ make -C linux LLVM=1 -j$(($(nproc) + 1)) \
 make -C linux LLVM=1 -j$(($(nproc) + 1)) \
     samples/rust/rust_minimal.o \
     samples/rust/rust_print.o \
-    drivers/net/phy/ax88796b_rust.o
+    drivers/net/phy/ax88796b_rust.o \
+    rust/doctests_kernel_generated.o
+
+make -C linux LLVM=1 -j$(($(nproc) + 1)) \
+    rustdoc
diff --git a/src/tools/miri/cargo-miri/src/setup.rs b/src/tools/miri/cargo-miri/src/setup.rs
index fe67aad465c..0cf6f1a375c 100644
--- a/src/tools/miri/cargo-miri/src/setup.rs
+++ b/src/tools/miri/cargo-miri/src/setup.rs
@@ -100,7 +100,10 @@ pub fn setup(
         // for target crates.
         let cargo_miri_path = std::env::current_exe().expect("current executable path invalid");
         if env::var_os("RUSTC_STAGE").is_some() {
-            assert!(env::var_os("RUSTC").is_some());
+            assert!(
+                env::var_os("RUSTC").is_some() && env::var_os("RUSTC_WRAPPER").is_some(),
+                "cargo-miri setup is running inside rustc bootstrap but RUSTC or RUST_WRAPPER is not set"
+            );
             command.env("RUSTC_REAL", &cargo_miri_path);
         } else {
             command.env("RUSTC", &cargo_miri_path);
diff --git a/src/tools/rustfmt/src/parse/macros/lazy_static.rs b/src/tools/rustfmt/src/parse/macros/lazy_static.rs
index 7baac247e22..b6de5f8691c 100644
--- a/src/tools/rustfmt/src/parse/macros/lazy_static.rs
+++ b/src/tools/rustfmt/src/parse/macros/lazy_static.rs
@@ -33,15 +33,17 @@ pub(crate) fn parse_lazy_static(
     }
     while parser.token.kind != TokenKind::Eof {
         // Parse a `lazy_static!` item.
+        // FIXME: These `eat_*` calls should be converted to `parse_or` to avoid
+        // silently formatting malformed lazy-statics.
         let vis = parse_or!(parse_visibility, rustc_parse::parser::FollowedByType::No);
-        parser.eat_keyword(kw::Static);
-        parser.eat_keyword(kw::Ref);
+        let _ = parser.eat_keyword(kw::Static);
+        let _ = parser.eat_keyword(kw::Ref);
         let id = parse_or!(parse_ident);
-        parser.eat(&TokenKind::Colon);
+        let _ = parser.eat(&TokenKind::Colon);
         let ty = parse_or!(parse_ty);
-        parser.eat(&TokenKind::Eq);
+        let _ = parser.eat(&TokenKind::Eq);
         let expr = parse_or!(parse_expr);
-        parser.eat(&TokenKind::Semi);
+        let _ = parser.eat(&TokenKind::Semi);
         result.push((vis, id, ty, expr));
     }
 
diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs
index 8ddacc07c6f..e2d1b85797f 100644
--- a/src/tools/tidy/src/error_codes.rs
+++ b/src/tools/tidy/src/error_codes.rs
@@ -319,7 +319,7 @@ fn check_error_codes_tests(
         if !found_code {
             verbose_print!(
                 verbose,
-                "warning: Error code {code}`` has a UI test file, but doesn't contain its own error code!"
+                "warning: Error code `{code}` has a UI test file, but doesn't contain its own error code!"
             );
         }
     }
diff --git a/tests/crashes/119716-2.rs b/tests/crashes/119716-2.rs
index 9cdc4417f5b..47bffb5c1de 100644
--- a/tests/crashes/119716-2.rs
+++ b/tests/crashes/119716-2.rs
@@ -1,4 +1,4 @@
 //@ known-bug: #119716
 #![feature(non_lifetime_binders)]
 trait Trait<T> {}
-fn f<T>() -> impl for<T> Trait<impl Trait<T>> {}
+fn f() -> impl for<T> Trait<impl Trait<T>> {}
diff --git a/tests/crashes/123809.rs b/tests/crashes/123809.rs
index c7a633aed01..75abe6dc0cd 100644
--- a/tests/crashes/123809.rs
+++ b/tests/crashes/123809.rs
@@ -1,4 +1,4 @@
 //@ known-bug: #123809
-type Positive = std::pat::pattern_type!(std::pat:: is 0..);
+type Positive = std::pat::pattern_type!(std::pat is 0..);
 
 pub fn main() {}
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index 6d335ac2def..cb1e5c325c2 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -239,6 +239,9 @@ pub unsafe extern "C" fn compatible_target_feature() {
 }
 
 #[doc = "foo bar baz"]
+/// a doc comment
+// a normal comment
+#[doc(alias = "ADocAlias")]
 #[naked]
 pub unsafe extern "C" fn compatible_doc_attributes() {
     asm!("", options(noreturn, raw));
diff --git a/tests/ui/backtrace/synchronized-panic-handler.rs b/tests/ui/backtrace/synchronized-panic-handler.rs
index 00eb249da1d..29431ae3c45 100644
--- a/tests/ui/backtrace/synchronized-panic-handler.rs
+++ b/tests/ui/backtrace/synchronized-panic-handler.rs
@@ -3,6 +3,7 @@
 //@ edition:2021
 //@ exec-env:RUST_BACKTRACE=0
 //@ needs-threads
+//@ needs-unwind
 use std::thread;
 const PANIC_MESSAGE: &str = "oops oh no woe is me";
 
diff --git a/tests/ui/backtrace/synchronized-panic-handler.run.stderr b/tests/ui/backtrace/synchronized-panic-handler.run.stderr
index b7c815a94c8..8a06d00ea59 100644
--- a/tests/ui/backtrace/synchronized-panic-handler.run.stderr
+++ b/tests/ui/backtrace/synchronized-panic-handler.run.stderr
@@ -1,5 +1,5 @@
-thread '<unnamed>' panicked at $DIR/synchronized-panic-handler.rs:10:5:
+thread '<unnamed>' panicked at $DIR/synchronized-panic-handler.rs:11:5:
 oops oh no woe is me
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-thread '<unnamed>' panicked at $DIR/synchronized-panic-handler.rs:10:5:
+thread '<unnamed>' panicked at $DIR/synchronized-panic-handler.rs:11:5:
 oops oh no woe is me
diff --git a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs
index 4ba696f4ae0..9f20cf08579 100644
--- a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs
+++ b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs
@@ -9,9 +9,10 @@ fn bug<const N: Nat>(&self)
 where
     for<const N: usize = 3, T = u32> [(); COT::BYTES]:,
     //~^ ERROR only lifetime parameters can be used in this context
-    //~^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders
-    //~^^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders
-    //~^^^^ ERROR failed to resolve: use of undeclared type `COT`
+    //~| ERROR defaults for generic parameters are not allowed in `for<...>` binders
+    //~| ERROR defaults for generic parameters are not allowed in `for<...>` binders
+    //~| ERROR failed to resolve: use of undeclared type `COT`
+    //~| ERROR  the name `N` is already used for a generic parameter in this item's generic parameters
 {
 }
 
diff --git a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr
index ee0ec38ab06..6037e685e44 100644
--- a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr
@@ -6,6 +6,15 @@ LL | fn bug<const N: Nat>(&self)
    |
    = note: associated functions are those in `impl` or `trait` definitions
 
+error[E0403]: the name `N` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/ice-predicates-of-no-entry-found-for-key-119275.rs:10:15
+   |
+LL | fn bug<const N: Nat>(&self)
+   |              - first use of `N`
+...
+LL |     for<const N: usize = 3, T = u32> [(); COT::BYTES]:,
+   |               ^ already used
+
 error[E0412]: cannot find type `Nat` in this scope
   --> $DIR/ice-predicates-of-no-entry-found-for-key-119275.rs:6:17
    |
@@ -40,7 +49,7 @@ error[E0433]: failed to resolve: use of undeclared type `COT`
 LL |     for<const N: usize = 3, T = u32> [(); COT::BYTES]:,
    |                                           ^^^ use of undeclared type `COT`
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0412, E0433, E0658.
-For more information about an error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0403, E0412, E0433, E0658.
+For more information about an error, try `rustc --explain E0403`.
diff --git a/tests/ui/traits/non_lifetime_binders/shadowed.rs b/tests/ui/traits/non_lifetime_binders/shadowed.rs
new file mode 100644
index 00000000000..1c480e3940b
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/shadowed.rs
@@ -0,0 +1,18 @@
+#![feature(non_lifetime_binders)]
+//~^ WARN the feature `non_lifetime_binders` is incomplete
+
+fn function<T>() where for<T> (): Sized {}
+//~^ ERROR the name `T` is already used for a generic parameter
+
+struct Struct<T>(T) where for<T> (): Sized;
+//~^ ERROR the name `T` is already used for a generic parameter
+
+impl<T> Struct<T> {
+    fn method() where for<T> (): Sized {}
+    //~^ ERROR the name `T` is already used for a generic parameter
+}
+
+fn repeated() where for<T, T> (): Sized {}
+//~^ ERROR the name `T` is already used for a generic parameter
+
+fn main() {}
diff --git a/tests/ui/traits/non_lifetime_binders/shadowed.stderr b/tests/ui/traits/non_lifetime_binders/shadowed.stderr
new file mode 100644
index 00000000000..59a073aefc9
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/shadowed.stderr
@@ -0,0 +1,44 @@
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowed.rs:4:28
+   |
+LL | fn function<T>() where for<T> (): Sized {}
+   |             -              ^ already used
+   |             |
+   |             first use of `T`
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowed.rs:7:31
+   |
+LL | struct Struct<T>(T) where for<T> (): Sized;
+   |               -               ^ already used
+   |               |
+   |               first use of `T`
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowed.rs:11:27
+   |
+LL | impl<T> Struct<T> {
+   |      - first use of `T`
+LL |     fn method() where for<T> (): Sized {}
+   |                           ^ already used
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowed.rs:15:28
+   |
+LL | fn repeated() where for<T, T> (): Sized {}
+   |                         -  ^ already used
+   |                         |
+   |                         first use of `T`
+
+warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/shadowed.rs:1:12
+   |
+LL | #![feature(non_lifetime_binders)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0403`.
diff --git a/tests/ui/type/pattern_types/missing-is.rs b/tests/ui/type/pattern_types/missing-is.rs
new file mode 100644
index 00000000000..2fbcc1908ef
--- /dev/null
+++ b/tests/ui/type/pattern_types/missing-is.rs
@@ -0,0 +1,8 @@
+#![feature(core_pattern_type, core_pattern_types)]
+
+use std::pat::pattern_type;
+
+fn main() {
+    let x: pattern_type!(i32 0..1);
+    //~^ ERROR expected one of `!`, `(`, `+`, `::`, `<`, or `is`, found `0`
+}
diff --git a/tests/ui/type/pattern_types/missing-is.stderr b/tests/ui/type/pattern_types/missing-is.stderr
new file mode 100644
index 00000000000..8ed654fe907
--- /dev/null
+++ b/tests/ui/type/pattern_types/missing-is.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `(`, `+`, `::`, `<`, or `is`, found `0`
+  --> $DIR/missing-is.rs:6:30
+   |
+LL |     let x: pattern_type!(i32 0..1);
+   |                              ^ expected one of `!`, `(`, `+`, `::`, `<`, or `is`
+
+error: aborting due to 1 previous error
+