about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs50
-rw-r--r--compiler/rustc_lint/src/traits.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs2
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs2
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs2
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs12
-rw-r--r--compiler/rustc_parse_format/Cargo.toml2
-rw-r--r--compiler/rustc_parse_format/src/lib.rs2
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs9
-rw-r--r--src/bootstrap/lib.rs2
-rw-r--r--src/bootstrap/llvm.rs4
-rw-r--r--tests/ui/borrowck/issue-114374-invalid-help-fmt-args.rs16
-rw-r--r--tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr33
-rw-r--r--tests/ui/drop-bounds/drop-bounds-impl-drop.rs10
-rw-r--r--tests/ui/fn/keyword-order.stderr2
-rw-r--r--tests/ui/parser/default-unmatched.stderr2
-rw-r--r--tests/ui/parser/impl-parsing.stderr2
-rw-r--r--tests/ui/parser/issue-101477-enum.stderr2
-rw-r--r--tests/ui/parser/issues/issue-113110-non-item-at-module-root.rs1
-rw-r--r--tests/ui/parser/issues/issue-113110-non-item-at-module-root.stderr10
-rw-r--r--tests/ui/parser/issues/issue-17904-2.stderr2
-rw-r--r--tests/ui/parser/issues/issue-43196.stderr2
-rw-r--r--tests/ui/parser/issues/issue-62913.stderr2
-rw-r--r--tests/ui/parser/issues/issue-68890.stderr2
-rw-r--r--tests/ui/parser/shebang/shebang-doc-comment.stderr2
-rw-r--r--tests/ui/parser/virtual-structs.stderr2
-rw-r--r--tests/ui/privacy/unnameable_types.rs8
-rw-r--r--tests/ui/pub/pub-restricted-error-fn.stderr2
-rw-r--r--tests/ui/unsafe/issue-115348-false-positive-warning-of-unnecessary-unsafe.rs16
-rw-r--r--tests/ui/unsafe/issue-115348-false-positive-warning-of-unnecessary-unsafe.stderr21
32 files changed, 192 insertions, 38 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 35a9fdccf9c..4cb2a584e6a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4175,7 +4175,7 @@ dependencies = [
 name = "rustc_parse_format"
 version = "0.0.0"
 dependencies = [
- "rustc_data_structures",
+ "rustc_index",
  "rustc_lexer",
 ]
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index fe4a45b3898..48d09f2c2b2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2130,21 +2130,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 /// misleading users in cases like `tests/ui/nll/borrowed-temporary-error.rs`.
                 /// We could expand the analysis to suggest hoising all of the relevant parts of
                 /// the users' code to make the code compile, but that could be too much.
-                struct NestedStatementVisitor {
+                /// We found the `prop_expr` by the way to check whether the expression is a `FormatArguments`,
+                /// which is a special case since it's generated by the compiler.
+                struct NestedStatementVisitor<'tcx> {
                     span: Span,
                     current: usize,
                     found: usize,
+                    prop_expr: Option<&'tcx hir::Expr<'tcx>>,
                 }
 
-                impl<'tcx> Visitor<'tcx> for NestedStatementVisitor {
-                    fn visit_block(&mut self, block: &hir::Block<'tcx>) {
+                impl<'tcx> Visitor<'tcx> for NestedStatementVisitor<'tcx> {
+                    fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
                         self.current += 1;
                         walk_block(self, block);
                         self.current -= 1;
                     }
-                    fn visit_expr(&mut self, expr: &hir::Expr<'tcx>) {
+                    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
                         if self.span == expr.span.source_callsite() {
                             self.found = self.current;
+                            if self.prop_expr.is_none() {
+                                self.prop_expr = Some(expr);
+                            }
                         }
                         walk_expr(self, expr);
                     }
@@ -2162,22 +2168,40 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             span: proper_span,
                             current: 0,
                             found: 0,
+                            prop_expr: None,
                         };
                         visitor.visit_stmt(stmt);
+
+                        let typeck_results = self.infcx.tcx.typeck(self.mir_def_id());
+                        let expr_ty: Option<Ty<'_>> = visitor.prop_expr.map(|expr| typeck_results.expr_ty(expr).peel_refs());
+
+                        let is_format_arguments_item =
+                            if let Some(expr_ty) = expr_ty
+                               && let ty::Adt(adt, _) = expr_ty.kind() {
+                                    self.infcx.tcx.lang_items().get(LangItem::FormatArguments) == Some(adt.did())
+                               } else {
+                                   false
+                               };
+
                         if visitor.found == 0
                             && stmt.span.contains(proper_span)
                             && let Some(p) = sm.span_to_margin(stmt.span)
                             && let Ok(s) = sm.span_to_snippet(proper_span)
                         {
-                            let addition = format!("let binding = {};\n{}", s, " ".repeat(p));
-                            err.multipart_suggestion_verbose(
-                                msg,
-                                vec![
-                                    (stmt.span.shrink_to_lo(), addition),
-                                    (proper_span, "binding".to_string()),
-                                ],
-                                Applicability::MaybeIncorrect,
-                            );
+                            if !is_format_arguments_item {
+                                let addition = format!("let binding = {};\n{}", s, " ".repeat(p));
+                                err.multipart_suggestion_verbose(
+                                    msg,
+                                    vec![
+                                        (stmt.span.shrink_to_lo(), addition),
+                                        (proper_span, "binding".to_string()),
+                                    ],
+                                    Applicability::MaybeIncorrect,
+                                );
+                            } else {
+                                err.note("the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used");
+                                err.note("to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>");
+                            }
                             suggested = true;
                             break;
                         }
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index 56508a2a6cc..e812493b3dd 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
             };
             let def_id = trait_predicate.trait_ref.def_id;
             if cx.tcx.lang_items().drop_trait() == Some(def_id) {
-                // Explicitly allow `impl Drop`, a drop-guards-as-Voldemort-type pattern.
+                // Explicitly allow `impl Drop`, a drop-guards-as-unnameable-type pattern.
                 if trait_predicate.trait_ref.self_ty().is_impl_trait() {
                     continue;
                 }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 7e745de4f1a..394b6aa1a06 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4363,7 +4363,7 @@ declare_lint! {
     ///     pub struct S;
     /// }
     ///
-    /// pub fn get_voldemort() -> m::S { m::S }
+    /// pub fn get_unnameable() -> m::S { m::S }
     /// # fn main() {}
     /// ```
     ///
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 0291cdd6c57..fbbdfe5f14f 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -2857,7 +2857,7 @@ impl<'tcx> Ty<'tcx> {
             | ty::Uint(..)
             | ty::Float(..) => true,
 
-            // The voldemort ZSTs are fine.
+            // ZST which can't be named are fine.
             ty::FnDef(..) => true,
 
             ty::Array(element_ty, _len) => element_ty.is_trivially_pure_clone_copy(),
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index 0fce9cb19a8..d5af321d726 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -483,7 +483,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResu
     // `mir_built` force this.
     let body = &tcx.mir_built(def).borrow();
 
-    if body.is_custom_mir() {
+    if body.is_custom_mir() || body.tainted_by_errors.is_some() {
         return tcx.arena.alloc(UnsafetyCheckResult {
             violations: Vec::new(),
             used_unsafe_blocks: Default::default(),
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 5d6c574baa6..c4e8d9006e6 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -106,7 +106,7 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
         let mut cursor_snapshot = self.cursor_snapshot.clone();
         let tokens =
             std::iter::once((FlatToken::Token(self.start_token.0.clone()), self.start_token.1))
-                .chain((0..self.num_calls).map(|_| {
+                .chain(std::iter::repeat_with(|| {
                     let token = cursor_snapshot.next();
                     (FlatToken::Token(token.0), token.1)
                 }))
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 233c7016417..aad4edaba90 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -73,12 +73,16 @@ impl<'a> Parser<'a> {
             if !self.maybe_consume_incorrect_semicolon(&items) {
                 let msg = format!("expected item, found {token_str}");
                 let mut err = self.struct_span_err(self.token.span, msg);
-                let label = if self.is_kw_followed_by_ident(kw::Let) {
-                    "consider using `const` or `static` instead of `let` for global variables"
+                let span = self.token.span;
+                if self.is_kw_followed_by_ident(kw::Let) {
+                    err.span_label(
+                        span,
+                        "consider using `const` or `static` instead of `let` for global variables",
+                    );
                 } else {
-                    "expected item"
+                    err.span_label(span, "expected item")
+                        .note("for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>");
                 };
-                err.span_label(self.token.span, label);
                 return Err(err);
             }
         }
diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml
index 72da398d3fc..14330353239 100644
--- a/compiler/rustc_parse_format/Cargo.toml
+++ b/compiler/rustc_parse_format/Cargo.toml
@@ -5,4 +5,4 @@ edition = "2021"
 
 [dependencies]
 rustc_lexer = { path = "../rustc_lexer" }
-rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_index = { path = "../rustc_index", default-features = false }
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 88452ccdf05..a6c7eb8d912 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -1011,7 +1011,7 @@ fn unescape_string(string: &str) -> Option<string::String> {
 
 // Assert a reasonable size for `Piece`
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Piece<'_>, 16);
+rustc_index::static_assert_size!(Piece<'_>, 16);
 
 #[cfg(test)]
 mod tests;
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 7e344dc516b..54cba1263b7 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -4,10 +4,17 @@ use super::{
     with, AllocId, DefId,
 };
 use crate::rustc_internal::Opaque;
+use std::fmt::{self, Debug, Formatter};
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone)]
 pub struct Ty(pub usize);
 
+impl Debug for Ty {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Ty").field("id", &self.0).field("kind", &self.kind()).finish()
+    }
+}
+
 impl Ty {
     pub fn kind(&self) -> TyKind {
         with(|context| context.ty_kind(*self))
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 4396bbc51a3..671d25484d0 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -1019,7 +1019,7 @@ impl Build {
 
     fn info(&self, msg: &str) {
         match self.config.dry_run {
-            DryRun::SelfCheck => return,
+            DryRun::SelfCheck => (),
             DryRun::Disabled | DryRun::UserSelected => {
                 println!("{msg}");
             }
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index 07502e0e9dd..aefed501513 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -598,9 +598,9 @@ fn configure_cmake(
         } else if target.contains("linux") {
             cfg.define("CMAKE_SYSTEM_NAME", "Linux");
         } else {
-            builder.info(
+            builder.info(&format!(
                 "could not determine CMAKE_SYSTEM_NAME from the target `{target}`, build may fail",
-            );
+            ));
         }
 
         // When cross-compiling we should also set CMAKE_SYSTEM_VERSION, but in
diff --git a/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.rs b/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.rs
new file mode 100644
index 00000000000..4a6c2f9ed06
--- /dev/null
+++ b/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.rs
@@ -0,0 +1,16 @@
+#![allow(dead_code)]
+
+fn bar<'a>(_: std::fmt::Arguments<'a>) {}
+fn main() {
+    let x = format_args!("a {} {} {}.", 1, format_args!("b{}!", 2), 3);
+    //~^ ERROR temporary value dropped while borrowed
+
+    bar(x);
+
+    let foo = format_args!("{}", "hi");
+    //~^ ERROR temporary value dropped while borrowed
+    bar(foo);
+
+    let foo = format_args!("hi"); // no placeholder in arguments, so no error
+    bar(foo);
+}
diff --git a/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr b/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr
new file mode 100644
index 00000000000..8221505b100
--- /dev/null
+++ b/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr
@@ -0,0 +1,33 @@
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/issue-114374-invalid-help-fmt-args.rs:5:13
+   |
+LL |     let x = format_args!("a {} {} {}.", 1, format_args!("b{}!", 2), 3);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
+   |             |
+   |             creates a temporary value which is freed while still in use
+...
+LL |     bar(x);
+   |         - borrow later used here
+   |
+   = note: the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used
+   = note: to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>
+   = note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/issue-114374-invalid-help-fmt-args.rs:10:15
+   |
+LL |     let foo = format_args!("{}", "hi");
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
+   |               |
+   |               creates a temporary value which is freed while still in use
+LL |
+LL |     bar(foo);
+   |         --- borrow later used here
+   |
+   = note: the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used
+   = note: to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>
+   = note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/drop-bounds/drop-bounds-impl-drop.rs b/tests/ui/drop-bounds/drop-bounds-impl-drop.rs
index 063efc7b31a..15aebdf1bc9 100644
--- a/tests/ui/drop-bounds/drop-bounds-impl-drop.rs
+++ b/tests/ui/drop-bounds/drop-bounds-impl-drop.rs
@@ -2,13 +2,13 @@
 #![deny(drop_bounds)]
 // As a special exemption, `impl Drop` in the return position raises no error.
 // This allows a convenient way to return an unnamed drop guard.
-fn voldemort_type() -> impl Drop {
-  struct Voldemort;
-  impl Drop for Voldemort {
+fn unnameable_type() -> impl Drop {
+  struct Unnameable;
+  impl Drop for Unnameable {
     fn drop(&mut self) {}
   }
-  Voldemort
+  Unnameable
 }
 fn main() {
-  let _ = voldemort_type();
+  let _ = unnameable_type();
 }
diff --git a/tests/ui/fn/keyword-order.stderr b/tests/ui/fn/keyword-order.stderr
index d3b140c8528..97d8f91b1ee 100644
--- a/tests/ui/fn/keyword-order.stderr
+++ b/tests/ui/fn/keyword-order.stderr
@@ -11,6 +11,8 @@ error: expected item, found keyword `pub`
    |
 LL | default pub const async unsafe extern fn err() {}
    |         ^^^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/parser/default-unmatched.stderr b/tests/ui/parser/default-unmatched.stderr
index 331e003f63c..de142411d69 100644
--- a/tests/ui/parser/default-unmatched.stderr
+++ b/tests/ui/parser/default-unmatched.stderr
@@ -11,6 +11,8 @@ error: expected item, found reserved keyword `do`
    |
 LL |     default do
    |             ^^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/parser/impl-parsing.stderr b/tests/ui/parser/impl-parsing.stderr
index 755addf1452..a57cc075ccc 100644
--- a/tests/ui/parser/impl-parsing.stderr
+++ b/tests/ui/parser/impl-parsing.stderr
@@ -35,6 +35,8 @@ error: expected item, found keyword `unsafe`
    |
 LL | default unsafe FAIL
    |         ^^^^^^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/parser/issue-101477-enum.stderr b/tests/ui/parser/issue-101477-enum.stderr
index 1edca391e8f..94130671f1c 100644
--- a/tests/ui/parser/issue-101477-enum.stderr
+++ b/tests/ui/parser/issue-101477-enum.stderr
@@ -11,6 +11,8 @@ error: expected item, found `==`
    |
 LL |     B == 2
    |       ^^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/parser/issues/issue-113110-non-item-at-module-root.rs b/tests/ui/parser/issues/issue-113110-non-item-at-module-root.rs
new file mode 100644
index 00000000000..3b6f4304369
--- /dev/null
+++ b/tests/ui/parser/issues/issue-113110-non-item-at-module-root.rs
@@ -0,0 +1 @@
+ 5 //~ ERROR expected item, found `5`
diff --git a/tests/ui/parser/issues/issue-113110-non-item-at-module-root.stderr b/tests/ui/parser/issues/issue-113110-non-item-at-module-root.stderr
new file mode 100644
index 00000000000..0789c4548a0
--- /dev/null
+++ b/tests/ui/parser/issues/issue-113110-non-item-at-module-root.stderr
@@ -0,0 +1,10 @@
+error: expected item, found `5`
+  --> $DIR/issue-113110-non-item-at-module-root.rs:1:2
+   |
+LL |  5
+   |  ^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
+
+error: aborting due to previous error
+
diff --git a/tests/ui/parser/issues/issue-17904-2.stderr b/tests/ui/parser/issues/issue-17904-2.stderr
index 9c7fdf6ccb4..7185a5e5752 100644
--- a/tests/ui/parser/issues/issue-17904-2.stderr
+++ b/tests/ui/parser/issues/issue-17904-2.stderr
@@ -3,6 +3,8 @@ error: expected item, found keyword `where`
    |
 LL | struct Bar<T> { x: T } where T: Copy
    |                        ^^^^^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to previous error
 
diff --git a/tests/ui/parser/issues/issue-43196.stderr b/tests/ui/parser/issues/issue-43196.stderr
index 4f7ed5cc6fd..15bbb158cd1 100644
--- a/tests/ui/parser/issues/issue-43196.stderr
+++ b/tests/ui/parser/issues/issue-43196.stderr
@@ -11,6 +11,8 @@ error: expected item, found `|`
    |
 LL | |
    | ^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/parser/issues/issue-62913.stderr b/tests/ui/parser/issues/issue-62913.stderr
index 6f385e8dc17..c33e4683728 100644
--- a/tests/ui/parser/issues/issue-62913.stderr
+++ b/tests/ui/parser/issues/issue-62913.stderr
@@ -17,6 +17,8 @@ error: expected item, found `"\u\"`
    |
 LL | "\u\"
    | ^^^^^^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/parser/issues/issue-68890.stderr b/tests/ui/parser/issues/issue-68890.stderr
index 2a3bf6b41f0..0d7b53a67c5 100644
--- a/tests/ui/parser/issues/issue-68890.stderr
+++ b/tests/ui/parser/issues/issue-68890.stderr
@@ -15,6 +15,8 @@ error: expected item, found `)`
    |
 LL | enum e{A((?'a a+?+l))}
    |                     ^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/parser/shebang/shebang-doc-comment.stderr b/tests/ui/parser/shebang/shebang-doc-comment.stderr
index 2227d45ec5a..a36b2a2f72b 100644
--- a/tests/ui/parser/shebang/shebang-doc-comment.stderr
+++ b/tests/ui/parser/shebang/shebang-doc-comment.stderr
@@ -3,6 +3,8 @@ error: expected item, found `[`
    |
 LL | [allow(unused_variables)]
    | ^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to previous error
 
diff --git a/tests/ui/parser/virtual-structs.stderr b/tests/ui/parser/virtual-structs.stderr
index a5211d83f84..268fc105796 100644
--- a/tests/ui/parser/virtual-structs.stderr
+++ b/tests/ui/parser/virtual-structs.stderr
@@ -3,6 +3,8 @@ error: expected item, found reserved keyword `virtual`
    |
 LL | virtual struct SuperStruct {
    | ^^^^^^^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to previous error
 
diff --git a/tests/ui/privacy/unnameable_types.rs b/tests/ui/privacy/unnameable_types.rs
index e35aaec5b3b..c6c5561c3c4 100644
--- a/tests/ui/privacy/unnameable_types.rs
+++ b/tests/ui/privacy/unnameable_types.rs
@@ -20,10 +20,10 @@ mod m {
     }
 }
 
-pub trait Voldemort<T> {}
+pub trait Unnameable<T> {}
 
-impl Voldemort<m::PubStruct> for i32 {}
-impl Voldemort<m::PubE> for i32 {}
-impl<T> Voldemort<T> for u32 where T: m::PubTr {}
+impl Unnameable<m::PubStruct> for i32 {}
+impl Unnameable<m::PubE> for i32 {}
+impl<T> Unnameable<T> for u32 where T: m::PubTr {}
 
 fn main() {}
diff --git a/tests/ui/pub/pub-restricted-error-fn.stderr b/tests/ui/pub/pub-restricted-error-fn.stderr
index 0511a821a7a..ca5d8e1b58e 100644
--- a/tests/ui/pub/pub-restricted-error-fn.stderr
+++ b/tests/ui/pub/pub-restricted-error-fn.stderr
@@ -11,6 +11,8 @@ error: expected item, found `(`
    |
 LL | pub(crate) () fn foo() {}
    |            ^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/unsafe/issue-115348-false-positive-warning-of-unnecessary-unsafe.rs b/tests/ui/unsafe/issue-115348-false-positive-warning-of-unnecessary-unsafe.rs
new file mode 100644
index 00000000000..68559338d49
--- /dev/null
+++ b/tests/ui/unsafe/issue-115348-false-positive-warning-of-unnecessary-unsafe.rs
@@ -0,0 +1,16 @@
+// Regression test for #115348.
+
+unsafe fn uwu() {}
+
+// Tests that the false-positive warning "unnecessary `unsafe` block"
+// should not be reported, when the error "non-exhaustive patterns"
+// appears.
+
+fn foo(x: Option<u32>) {
+    match x {
+        //~^ ERROR non-exhaustive patterns: `None` not covered
+        Some(_) => unsafe { uwu() },
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/unsafe/issue-115348-false-positive-warning-of-unnecessary-unsafe.stderr b/tests/ui/unsafe/issue-115348-false-positive-warning-of-unnecessary-unsafe.stderr
new file mode 100644
index 00000000000..7384899b978
--- /dev/null
+++ b/tests/ui/unsafe/issue-115348-false-positive-warning-of-unnecessary-unsafe.stderr
@@ -0,0 +1,21 @@
+error[E0004]: non-exhaustive patterns: `None` not covered
+  --> $DIR/issue-115348-false-positive-warning-of-unnecessary-unsafe.rs:10:11
+   |
+LL |     match x {
+   |           ^ pattern `None` not covered
+   |
+note: `Option<u32>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<u32>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Some(_) => unsafe { uwu() },
+LL ~         None => todo!(),
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.